原来知道 执行的过程 ,但是对于执行过程中的等待事件却不是太了解 ,这里详细说明了。
sql语句执行过程:
1 对sql语句进行语义、语法、对象是否存在做过检查后,获得hash bucket的library cache
lock,检查library cache中是否存在此sql,如果存在,就是soft parse(转到第八步),获得library
cache的过程如果发生争用即是latch:library cache
2 如果不存在 则获得shared pool的锁存器,在shared pool中寻找合适的chunk, 这时如果出现争用即
latch:shared pool
3 在shared
pool中的空闲列表中搜索合适的chunk,如果没有找到合适的,就找大的chunk,把大的chunk分割成小的,并把剩余的放到合适的空闲列表中。
4 如果在空闲列表中没有找到,则在LRU的可再使用(recreatable)中寻找,
5 若找不到合适的chunk,则追加已经分配给shared pool的空间
6 如果以上步骤都失败,则 报04031错误
7 找到合适的chunk,对sql相应的handle以 独占模式library cache lock, 然后把library
cache lock模式改为Null,以独占模式获得library cache pin 生成执行计划,
8 对sql cursor以shared模式获得到library cache lock 和library cache
pin
9 执行sql fetch数据时,把library cache lock 模式变为null,并释放library cache
pin
因为争用latch:library cache代价较高,所以oracle也尽量减少争用,
1 对于pl/sql里经常执行的sql cursor,只有在最初执行时parse,之后没有soft
parse也就没有竟争library cache,oracle把相应的sql cursor
pin在sga中
2 对于在同一个session中执行三次以上的 sql,则把sql cursor和sql文本 pin 在
PGA中,(能pin 的个数取决于session_cached_cursors) ,即使这样,不是需要library
cache锁存器,只是不用到shared pool 中去搜索 ,减少了持有 latch:library cache的时间。