shared pool锁存器起到保护堆(共享池的基本内存结构)的作用。为了查找free chunk,检索空闲列,分配适当的chunk,必要时分隔空闲chunk的一连串工作,全都只能在获得shared pool锁存器后才能发生。在获得shared pool锁存器过程中发生争用,则等待latch: shared pool事件。
SQL> select name,parameter1,parameter2,parameter3 from v$event_name where name like 'latch: shared pool';
NAME PARAMETER1 PARAMETER2 PARAMETER3
------------------------------ -------------------- -------------------- --------------------
latch: shared pool address number tries
shared pool锁存器一般在整个实例上只存在一个。即,一个共享池上使用一个shared pool锁存器。这是基与共享池基本内存结构——堆的结构决定的。因此,多个会话同时想要分配到chunk时,为了获得唯一的shared pool锁存器发生争用。
oracle 9i以上版本开始,共享次可分为多个副池(最多7个)进行管理。利用_KGHDSIDX_COUNT隐含参数,可管理副池的数量。因此,共享池较大时分为多个副池管理,所以能减少shared pool锁存器争用。通过如下语句可以看见数据库中的shared pool数量:
- SQL> select count(*) from v$latch_children where name = 'shared pool';
- COUNT(*)
- ----------
- 7
若发生了Hard Parsing,为了分配到保存sql信息的chunk,应检索空闲列。进行这些操作过程中,只能由一个进程独占shared pool锁存器,因此多个会话执行Hard Parsing时,较多发生shared pool锁存器等待。因此在过多发生Hard Parsing的系统上,为了减少shared pool锁存器等待,加大共享池大小是非常危险的想法。最好的解决方法就是为避免发生Hard Parsing,恰当使用bind变量。
在执行sql发生Hard Parsing时,oracle首先在获得library cache锁存器状态下检索库高速缓冲区,此状态下获得shared pool锁存器。从而在library cache锁存器获取接阶段因发生争用,而发生瓶颈现象时,相对latch: shared pool等待就可能出现的少。即便发生相同数量的Hard Parsing,多个会话同时执行Parsing时,为寻找chunk在获得shared pool锁存器之前,为了检索库高速缓冲区,在获得library cache锁存器过程中发生争用。因此这时latch: library cache等待显得较高,latch: shared pool等待显得相当低。