库缓存实际上是SGA中的一块内存区域(更确切地说,库缓存是Shared Pool中的一块内存区域),它的主要作用是缓存刚刚执行过的SQL语句和PL/SQL语句所对应的执行计划、解析树等对象,当同样的SQL语句和PL/SQL语句再次被执行时,就可以利用已经缓存在Library Cache中的那些相关对象而无须再次从头开始解析,这样就提高了这些SQL语句和PL/SQL语句在重复执行时的执行效率。
Library Cache在SGA中的位置:

缓存在库缓存中的对象称之为库缓存对象(Library Cache Object),所有的库缓存对象都是以一种名为库缓存对象名柄(Library Cache Ojbect Handle),的结构存储在库缓存中,Oracle是通过访问相关的库缓存对象句柄来访问对应的库缓存对象的。
实际上,库缓存对象句柄是以哈希表(Hash Table)的方式存储在库缓存中的,这意味着Oracle会通过相关的哈希运算来存储和访问对应的库缓存对象句柄。
站在哈希表的角度,则整个库缓存的组成结构:

整个库缓存可以看作是由一组Hash Bucket所组成,每一个Hash Bucket都对应不同的哈希值。对于单个Hash Bucket而言,里面存储的就是哈希值相同的有的库缓存对象句柄,同一个Hash Bucket中不同的库缓存对象句柄之间会用指针连接起来,即同一个Hash Bucket中不同的库缓存对象句柄之间实际上组成了一个库缓存对象句柄链表(Library Cache Ojbect Handles)。
从上图中可以看出,当Oracle要执行目标SQL “select * from emp”时,首先会对该SQL的SQL文本施以哈希运算,然后根据得到的哈希值去相关的Hash Bucket中遍历对应的库缓存对象句柄链表,如果找到了对应的库缓存对象句柄,就可以直接访问到该SQL的执行计划、解析树等对象,这意味着可以直接重用这些对象而无须再次从头开始解析;如果找到不对应的库缓存对象句柄,则意味着必须从并没有开始解析,并且把解析后的执行计划、解析树等对象以库缓存对象句柄的方式链接在相关的Hash Bucket中的库缓存对象句柄链表中。
库缓存对象句柄就是Oracle自定义的一种C语言复杂结构:

从上图中可以看出,作为一种C语言复杂结构,库缓存对象句柄有很多属性,每一个属性都有其特定的作用。这里介绍Name、Namespace和Heap 0 Pointer这三个属性。
属性“Name”表示的是库缓存对象句柄所对应的库缓存对象的名称。
属性“Namespace”表示的是库缓存对象句柄对应的库缓存对象所在的分组名,不同类型的库缓存对象可能属于同一个分组,即不同类型的库缓存对象所对应的库缓存对象句柄的Namespace值有可能是相同的。
常见的Namespace值及其含义
| Namespace值 | 含义 |
|---|---|
| CRSR | SQL语句和匿名PL/SQL语句所对应的库缓存对象句柄的Namespace的值均为“CRSR" |
| TABL/PRCD/TYPE | 表、视图、Sequence、同义词、存储过程、函数、Type和Package的定义所对应的库缓存对象句柄的Namespace的值均为“TABL/PRCD/TYPE" |
| BODY/TYBD | Type和Package的具体实现(Body)所对应的库缓存句柄的Namespace的值均为”BODY/TYDB" |
| TRGR | Trigger所对应的库缓存对象句柄的Namespace的值为“TRGR” |
| INDX | 索引所对应的库缓存对象句柄的Namespace的值为“INDX” |
| CLST | Cluster所对应的库缓存对象句柄的Namespace的值的“CLST” |
| … | … |
库缓存对象句柄结构里嵌套结构。属性“Heap 0 Pointer”就是指向子结构Heap 0的指针。Heap 0也是一种复杂结构,它也有很多属性,每一个属性都有其特性的作用。




