有台Oracle数据库服务器,发现内存占用得比较厉害,生成awr报告,发现有个指标有点异常
Instance Efficiency Percentages (Target 100%)
Buffer Nowait %: | 100.00 | Redo NoWait %: | 100.00 |
Buffer Hit %: | 100.04 | In-memory Sort %: | 100.00 |
Library Hit %: | 98.33 | Soft Parse %: | 98.96 |
Execute to Parse %: | -13.40 | Latch Hit %: | 99.95 |
Parse CPU to Parse Elapsd %: | 98.77 | % Non-Parse CPU: | 72.78 |
里面的Execute to Parse 居然出现负数。找到某大师给出的该参数计算公式如下:
Execute to Parse = round(100*(1-:prse/:exe),2)
prse = select value from v$sysstat where name = 'parse count (total)';
exe = select value from v$sysstat where name = 'execute count';
也就是说,这个参数的值,主要是体现 SQL的 解析次数与执行次数的比率。而且这里的解析包括硬解析和软解析、软软解析。
SQL的执行包括几个步骤:打开、解析、绑定、执行、抓取、关闭。
解析的时候确定执行计划,硬解析就是重新生成执行,软解析是在共享池中找到了执行计划,软软解析是让查找执行计划的过程更短、更快。但无论软解析、还是软软解析,都有解析这个操作。
要改善解析与执行的比率关系,就需要增加无解析的次数,无解析就是不再解析,为SQL绑定不同的变量,然后执行。这样做的前提就是:1、Session不能断开;2、Session执行过解析过的SQL不要关闭;满足这两点就可以实现无解析。
下面,就介绍一个和这个有密切关系的参数:session_cached_cursors
session_cached_cursors,就是说的是一个session可以缓存多少个cursor,让后续相同的SQL语句不再打开游标,从而避免软解析的过程来提高性能。(绑定变量是解决硬解析的问题),软解析同硬解析一样,比较消耗资源.所以这个参数非常重要。
oracle有一个概念,那就是session cursor cache,中文描述就是有一块内存区域,用来存储关闭了的cursor。当一个cursor关闭之后,oracle会检查这个cursor的request次数是否超过3次,如果超过了三次,就会放入session cursor cache,这样在下次parse的时候,就可以从session cursor cache中找到这个statement, session cursor cache的管理也是使用LRU。
session_cached_cursors这个参数是控制session cursor cache的大小的。session_cached_cursors定义了session cursor cache中存储的cursor的个数。这个值越大,则会消耗的内存越多。
另外检查这个参数是否设置的合理,可以从两个statistic来检查。
select name,value from v$sysstat where name like '%cursor%';
select name,value from v$sysstat where name like '%parse%';
session cursor cache hits 和parse count(total) 就是总的parse次数中,在session cursor cache中找到的次数,所占比例越高,性能越好。如果比例比较低,并且有剩余内存的话,可以考虑加大该参数。
到这里,我们就明白了,基于上面的情况,我们应该调整哪个参数,才能真正解决问题。
alter system set session_cached_cursors=100 scope=spfile;
修改后要重启数据库方能生效。