共享池调优
在一个产品数据库中,共享池吸引了你的大多数注意力,因为它直接关系到应用的性能。共享池是SGA的组成部分,它保存几乎所有执行SQL语句和PL/SQL程序所必要的元素。除高速緩存程序代码外,共享池还高速缓存Oracle在程序执行中经常需要的数据字典信息。
合理地共享池配置会带来极大的性能改善。不恰当地调优共享池会导致如下问题:
Ø 增加了闩争用,同时需要更多的CPU资源;
Ø 因为SQL的可执行形式未在共享池中给出而导致了较大的I/O;
Ø 因为不必要的SQL代码分析而导致较多地使用CPU。
当在产品数据库的速度严重下降时,观察到的共享池等待和其他等待的全面增加是SQL代码不能使用绑定变量的结果。
随着用户数目的增加,也要求增加共享内存和闩,闩为内存区中的内部锁。如果存在过多的闩,会导致较高的等待时间和较低的响应时间。甚至是整个数据库好像停止运行了。
共享池由两个主要区域组成,分别是库高速缓存和数据字典高速缓存。不能分配或减少专门用于这两个组件中的某一个组件的内存。如果增加总共享池的内存尺寸,则两个组件都将会按Oracle确定的某种比例增加。类似地,如果减少总的共享池内存,则两个组件的尺寸都将减少。我们来详细考察一下这两个重要的共享池组件。
1.库高速缓存
库高速缓存(library cache)保存SQL和PL/SQL代码的分析过的、可执行的版本。可以回忆一下第19章的内容,所有SQL语句在他们的处理过程中都要经历以下的处理步骤。
Ø 分析:包括SQL语句的句法和语义检验,并检査所执行活动的对象权限。
Ø 优化:Oracle优化程序在评估了几个备选模式后,得岀如何以最低成本处理相应语句的方案。
Ø 执行:Oracle利用优化过的物理执行计划来执行SQL语句中规定的活动。
Ø 取数据:只用于Oracle必须返回行的SELECT语句。这个步骤在非查询型的语句中不需要。
分析是一种资源密集型的操作,如果应用需要重复执行相同的SQL语句,内存中有一个分析过的版本将减少闩、CPU、I/O、内存等的争用。在Oracle第一次分析一个SQL语句时,它将创建一棵分析树(parse tree).
仅在第一次执行一条SQL语句时需要优化步骤。优化了语句后,则最佳的访问路径将被封装在访问计划(access plan)中。分析树和访问计划都将在语句第一次执行前存储在库高速缓存中。
将来调用相同语句仅需要最后一步,即执行。这样,只要Oracle能在库高速缓存中找到相应语句的分析树和访问计划,就能免去分析和优化的开销。当然,如果相应的语句是一条SQL查询,最后一步将是取数据操作。
由于受到尺寸的限制,如果没有更多的空间用于新SQL语句时,库高速缓存将丢弃旧的SQL语句。能将分析过的语句重复用于多次执行的唯一方式是新SQL语句与分析过的语句等同。如果两条SQL语句使用完全相同的代码,包括字母的大小写和空格都相同,则说这两条SQL语句是等同的。
之所以这样定义是因为Oracle在将新语句与库高速缓存中己有的语句进行比较时,釆用的是简单的字符串比较。此外,所使用的任意绑定变量必须在数据类型和大小方面也是相似的。下面举几个例子,说明Oracle在判断两条SQL语句是否等同时是如何地严谨。
2.字典高速缓存
正如前面所提到的那样,字典髙速缓存缓存数据字典信息。此高速缓存比库高速缓存小得多,为了增加或减少它,需要修改相关共享池。如果适当地配置了库高速缓存,很可能字典髙速缓存也已经配置好了。可使用下面的查询得到关于数据字典高速缓存效能的一个直观的看法:
select (sum(gets - getmisses - fixed)) / sum(gets) "data dictionary hit ratio" from v$rowcache;
通常,应当尽量争取使数据字典的命中率达到95%-99%,虽然Oracle有时认为达到85%就够了。为了増加库高速缓存命中率,简单地增加实例的共享池尺寸即可。