首先了解一下excute to parse%的概念
这个参数的值,主要是体现 的 解析次数与执行次数的比率。而且这里的解析包括硬解析和软解析、软软解析
计算方式
execute to parse %= round(100*(1-prse/exe),2)
理想百分比为100%及接近于只执行而不解析
数据来源如下
prse = select value from v$sysstat where name = ‘parse count (total)’;
exe = select value from v$sysstat where name = ‘execute count’;
正负值说明
如果系统Parses > Executions,就可能出现该比率小于 0 的情况。该值<0 通常说明 shared pool 设置或者语 句效率存在问题,造成反复解析,reparse 可能较严重,或者是可能同 snapshot 有关,通常说明数据库性能存在一定问题
影响因素
session_cached_cursor(就是说的是一个 session 可以缓存多少个 cursor ,让后续相同的 SQL 语句不再打开游标 , 从而避免软解析的过程来提高性能。)
open_cursor(同一个 session 同时打开最多在使用的游标数)
绑定变量(硬解析、软解析)
那么execute to parse%低数据库中解析效率一定会差吗?通过2个例子来验证
例1
业务较繁忙的库
上图1中图2可以关联起来运用计算公式如下
SQL> select 1-(16755.9/17306.4) from dual;
1-(16755.9/17306.4)
——————-
.031809042
与awr报告中excute to parse %数值相符,一般情况下此数值大于0
数值说明:当值为3.18时不足以说明解析存在性能问题,需要看另外一个性能指标soft parse %。如果soft parse %高,而excute to parse %低时说明硬解析多,建议使用绑定变量。当Soft Parse %高,而Execute to Parse %比低时(<40%),说明执行解析比率低,可以通过静态sql、动态绑定、调整session_cached_cursor参数、调整open_cursor等方法来减少软解析
cursor使用情况查询
SQL> Select ‘session_cached_cursors’ Parameter,
2 Lpad(Value, 5) Value,
3 Decode(Value, 0, ‘ n/a’, To_Char(100 * Used / Value, ‘990’) || ‘%’) Usage
4 From (Select Max(s.Value) Used
5 From V$statname n, V$sesstat s
6 Where n.Name = ‘session cursor cache count’
7 And s.Statistic# = n.Statistic#),
8 (Select Value From V$parameter Where Name = ‘session_cached_cursors’)
9 Union All
10 Select ‘open_cursors’,
11 Lpad(Value, 5),
12 To_Char(100 * Used / Value, ‘990’) || ‘%’
13 From (Select Max(Sum(s.Value)) Used
14 From V$statname n, V$sesstat s
15 Where n.Name In
16 (‘opened cursors current’, ‘session cursor cache count’)
17 And s.Statistic# = n.Statistic#
18 Group By s.Sid),
19 (Select Value From V$parameter Where Name = ‘open_cursors’);
PARAMETER VALUE USAGE
———————- ———- —–
session_cached_cursors 500 100%
open_cursors 2000 25%
可以看到session_cached_cursors利用率已经达到了100%,说明会话打开的游标数已充分利用,但是value是否合理需要看另外一个比值cursor cache hits/ parse count(total),二者比值越高,性能越好。如果比例比较低,并且有较多剩余内存的话,可以考虑加大该参数
cursor cache hits 就是系统在高速缓存区中找到相应 cursors 的次数
parse count(total) 就是总的解析次数
下面我们用计算说明
SQL> select name,to_char(value) from v$sysstat where name like ‘%cursor%’;
NAME TO_CHAR(VALUE)
———————————– —————————————-
opened cursors cumulative 28802682928
opened cursors current 18530
pinned cursors current 526
session cursor cache hits 28259016630
session cursor cache count 241161764
cursor reload failures 4294
cursor authentications 6077530
7 rows selected.
select name,to_char(value) from v$sysstat where name like ‘%parse%’;
NAME TO_CHAR(VALUE)
———————————— —————————————-
ADG parselock X get attempts 0
ADG parselock X get successes 0
parse time cpu 12940072
parse time elapsed 66911926
parse count (total) 27048745669
parse count (hard) 35046636
parse count (failures) 261711
parse count (describe) 4001
8 rows selected.
比值说明
SQL> select 28259016630/27048745669 from dual;
28259016630/27048745669
———————–
1.04474407
到这我们就会发现,虽然session_cached_cursors利用率已经达到了100%,但是session cursor cache hits的比值较低,为了能够减少解析的次数提高游标利用可以适当加大session_cached_cursors参数,提高解析执行比率
例2
计算值如下
select 1-(24.8/50.3) from dual;
SQL> select 1-(24.8/50.3) from dual;
1-(24.8/50.3)
————-
.50695825
数值说明:图中看到execute to parse %已达到50%,soft parse %为99.65%。那么是否可以判断,数据库中sql解析性能良好?看下面的计算数值
Cache使用情况查询
SQL> Select ‘session_cached_cursors’ Parameter,
2 Lpad(Value, 5) Value,
3 Decode(Value, 0, ‘ n/a’, To_Char(100 * Used / Value, ‘990’) || ‘%’) Usage
4 From (Select Max(s.Value) Used
5 From V$statname n, V$sesstat s
6 Where n.Name = ‘session cursor cache count’
7 And s.Statistic# = n.Statistic#),
8 (Select Value From V$parameter Where Name = ‘session_cached_cursors’)
9 Union All
10 Select ‘open_cursors’,
11 Lpad(Value, 5),
12 To_Char(100 * Used / Value, ‘990’) || ‘%’
13 From (Select Max(Sum(s.Value)) Used
14 From V$statname n, V$sesstat s
15 Where n.Name In
16 (‘opened cursors current’, ‘session cursor cache count’)
17 And s.Statistic# = n.Statistic#
18 Group By s.Sid),
19 (Select Value From V$parameter Where Name = ‘open_cursors’);
PARAMETER VALUE USAGE
———————- ———- —–
session_cached_cursors 300 394%
open_cursors 300 398%
通过计算数值发现,上述两个参数利用率已经接近于400%,这种情况下增加参数的value值很有必要,我们继续看下面的游标命中率
cursor cache hits/ parse count(total)计算
NAME TO_CHAR(VALUE)
——————————– —————————————-
opened cursors cumulative 127503542508
opened cursors current 1067
pinned cursors current 237
session cursor cache hits 93992188584
session cursor cache count 4186337347
cursor reload failures 1088012
cursor authentications 425820846
7 rows selected.
NAME TO_CHAR(VALUE)
——————————– —————————————-
ADG parselock X get attempts 0
ADG parselock X get successes 0
parse time cpu 12940072
parse time elapsed 66911926
parse count (total) 27048745669
parse count (hard) 35046636
parse count (failures) 261711
parse count (describe) 4001
8 rows selected.
比值说明
SQL> select 93992188584/27048745669 from dual;
93992188584/27048745669
———————–
3.47491857
通过计算发现本例中的比值要比例1中的高,这和上面cursor usage的数值密不可分。判断open_cusor是否合理的话可以通过查询历史游标打开的最大值来分析,历史最大打开游标数小于数据库中参数设置值时合理。
数值建议:session cursor cache hits/parse count (total)
这个比值较低时在内存充足的情况下可以设当调整session_cached_cursors的值来提高数据库的性能。
Execute to Parse相关知识拓展
当我们执行一条sql语句的时候,我们将会在shared pool产生一个library cache object,cursor就是其中针对于sql语句的一种library cache object. 另外我们会在pga有一个cursor的拷贝,同时在客户端会有一个statement handle,这些都被称为cursor,在v$open_cursor里面我们可以看到当前打开的cursor和pga内cached cursor
session_cached_cursor(此参数在内存中的管理引用了lru技术)
这个参数限制了在pga内session cursor cache list的长度,session cursor cache list是一条双向的lru链表,当一个session打算关闭一个cursor时,如果这个cursor的parse count超过3次, 那么这个cursor将会被加到session cursor cache list的MRU端. 当一个session打算parse一个sql时,它会先去pga内搜索session cursor cache list,如果找到那么会把这个cursor脱离list,然后当关闭的时候再把这个cursor加到MRU 端.session_cached_cursor提供了快速软分析的功能,提供了比soft parse更高的性能,也就是说连open cursor的动作都给省了
总结
Awr报告中execute to parse %的大小不能直观做出判断数据库中解析存在性能问题,需要结和soft parse%(一般就在99%左右)
通过对比两个例子发现当soft parse%值差别不大时,execute to parse %的值较大的库,只能说sql语句解析一次执行多次,这是一个好的征兆。继续判断cursor的命中率与解析次数比值时发现,游标需要频繁的在内存中交换,这是sql解析还是存在性能瓶颈。
如何来保证数据库中的解析与执行在一个健康的状态下,这种时候需要通过awr中execute to parse %值的表象来分析影响他的制约因素,来调整相关的参数或使用绑定变量来优化数据库性能。
注意
需要加大参数 session_cached_cursors 来提高 oracle 数据库的性能时,要注意 session_cached_cursors并不是越大越好,太大会引起pga缓存碎片,消耗内存。
参数调整需要结和sga和pga的大小及使用情况