我们只能设置shared pool的大小,不能设置里面librarycache和row cache的大小。
Free的内存结构:
Free空间由一个个小的内存块(chunk,图中圆圈)组成,然后用链(chain)把内存块挂到链上。图中所示的三个链由上到下所挂的内存块的大小越来越大。
硬解析时根据SQL执行计划的大小,从free区中分配合适的内存块给执行计划,并把内存块移到library cache里。
假设一种情况:上图由上到下三个链的大小是4K、8K、12K,此时一个执行计划需要10K,那么就从12K的链上取出一块内存,分成两半,一半10K给执行计划,另一半2K挂到更小的链上。
过多的硬解析容易造成碎片,虽然free区有很多空间但是都是小碎片,不能使用。如果SQL找不到合适大小的内存块(chunk),这是会报ORA-4031错误。
ORA-4031错误产生的原因:
1. 大量的硬解析;
2. 大量硬解析产生大量小碎片以后突然又来了一些比较长的SQL语句,长SQL需要大空间,这个时候空间就不够了;
链:可以把内存块串起来;所有的内存块都挂在链上,链可以遍历;oracle大量使用链技术,链由锁(latch)来保护
library cache的内存结构:
跟free一样也是由链组成,但是挂载链上的内存块写的有内容。内容就是SQL语句以及对应的执行计划(plan)。
硬连接发生时,free上的chunk挂到library cache上的过程:
1. SQL语句所有的字母被server process解析成ASCII码值,SQL语句被变成一串数字了;
2. 然后对这一串数字进行运算,得到一个数字,这个数字就是library cache中链的编号;
3. Server process把SQL语句以及对应的执行计划挂到算出编号的链上;
4. 当再次执行这条SQL语句时,server process执行步骤1-2,得到链编号,链上挂着很多chunk,server process用锁(latch)把链锁上,遍历链,找到chunk以后就是软解析了;
查看shared pool里面有多少个chunk:
SQL> select count(*) from x$ksmsp; COUNT(*) ---------- 21942
发生一次硬解析:
> select count(*) from dba_indexes; COUNT(*) ---------- 2344
然后再查chunk数:
SQL> select count(*) from x$ksmsp; COUNT(*) ---------- 21971
清空library cache和row cache:
<pre name="code" class="sql">SQL> alter system flushshared_pool; System altered.
清空之后执行任何一条语句都会发生硬解析,同时ORA-4031错误立马减少。