select 的工做原理:
1:Parse,语法分析阶段
2:Execute,执行
3:Fetch,提取数据阶段
一:先在Library Cache找这条命令,看执行计划,
二:若是没有,就语法分析
三:若是语法经过,就对象分析,经过数据字典
好比表存不存在,表列存不存在,表列若是是*,就翻译成所有列名
四:得到对象解析锁,锁住表,列这个对象,目的是防止别的用户来改变表,列结构。
五:检查权限对象,看用户能不能访问这个对象。好比表,视图。
六:服务器生成执行计划,装载到Library Cache中
七:检查
数据库高速缓存区(Data buffer)中,有没有内容,即看能不能找到对象(表,视图)的数据块(block),若是有,就返回
八:若是不存在,由服务器进程,把表块读取到Data Buffer中
九:把Data Buffer中的数据提取出来.
update语句分析:
1:Parse阶段
2:Execute阶段
一:先在Library Cache找这条命令,看执行计划,
二:若是没有,就语法分析
三:若是语法经过,就对象分析,经过数据字典
好比表存不存在,表列存不存在
四:得到对象解析锁,锁住表,列这个对象,目的是防止别的用户来改变表,列结构。
五:检查权限对象,看用户能不能访问这个对象。好比表,视图。
六:服务器生成执行计划,装载到Library Cache中
七:检查数据库高速缓存区(Data buffer)中,要修改的内容的行(数据块)存不存在,若是存在,就修改
八:若是不存在,由服务器进程,把表块读取到Data Buffer中
九:给被修改的行加锁,以防止其它用户对对象(表)的结构进行修改。
十:旧数据放到Undo buffer(回滚段)中,新数据写时去,这个改变状态记录到Redo Logo中(Redo 日志/重作日志)
删除(DELETE)
1.Oracle读Block到Buffer Cache(若是该Block在Buffer中不存在)
2.在redo log buffer中记录delete操做的细节
3.在相应回滚段段头的事务表中建立一个undo条目
4.把将要删除的记录建立前镜像,存放到Undo Block中
5.在Buffer Cache中的相应数据块上删除记录,而且标记相应的数据块为Dirty
提交(COMMIT)
1.Oracle产生一个SCN
2.在回滚段事务表中标记该事务状态为commited
3.LGWR Flush Log Buffer到日志文件
3.若是此时数据块仍然在Buffer Cache中,那么SCN将被记录到Block Header上,这被称为快速提交(fast commit)
4.若是dirty block已经被写回到磁盘,那么下一个访问这个block的进程将会自回滚段中获取该事务的状态,确认该事务被提交。而后这个进程得到提交SCN并写回到Block Header上。这被称为延迟块清除(delayed block cleanout)。
我的疑惑待解决问题:
对于insert into table1 (id) values(select max(id)+1 from table2) 这种sql,并发会不会引发id重复???
合并链接(Sort Merge Join, SMJ):
a) 对于非等值链接,这种链接方式的效率是比较高的。
b) 若是在关联的列上都有索引,效果更好。
c) 对于将2个较大的row source作链接,该链接方法比NL链接要好一些。
d) 可是若是sort merge返回的row source过大,则又会致使使用过多的rowid在表中查询数据时,数据库性能降低,由于过多的I/O.html
嵌套循环(Nested Loops, NL):
a) 若是driving row source(外部表)比较小,而且在inner row source(内部表)上有惟一索引,或有高选择性非惟一索引时,使用这种方法能够获得较好的效率。
b) NESTED LOOPS有其它链接方法没有的的一个优势是:能够先返回已经链接的行,而没必要等待全部的链接操做处理完才返回数据,这能够实现快速的响应时间。sql
哈希链接(Hash Join, HJ):
a) 这种方法是在oracle7后来引入的,使用了比较先进的链接理论,通常来讲,其效率应该好于其它2种链接,可是这种链接只能用在CBO优化器中,并且须要设置合适的hash_area_size参数,才能取得较好的性能。
b) 在2个较大的row source之间链接时会取得相对较好的效率,在一个row source较小时则能取得更好的效率。
c) 只能用于等值链接中数据库