1)开发组的所有成员都使用相同的编码规范(包括大小写,空格,换行等);
2)使用绑定变量(提高命中率的同时可能会产生不够好的执行计划,因为优化器不知道变量的确定值,在有栏位的柱状图统计数据时也不能够利用)。
调整相关初始化参数:
OPEN_CURSOR
这个参数指定每个用户会话能打开的游标最大数量;增大这个值可以减少重新解析会话曾打开的语句的机会,提高命中率,但需要更大的共享池空间。要确保该值足够,增加该值不会对内存造成太大的影响
cursor_space_for_time
缺省是FALSE,如果设置为TRUE,那么SHARED SQL AREA当CURSOR打开的时候,是PIN在共享池里的,不允许被换出(AGEOUT),这样提高了SQL的执行效率,另外PGA中的CURSOR的私有内存部分,执行完SQL后也不关闭,下次执行的时候可以直接使用,节省了内存分配和释放的时间。对于同一个SQL反复被执行的情况,这种设置有助于提高 SQL执行的效率。但是这个参数设置会增加共享池的使用。如果共享池出现不足,或者碎片很严重的情况,使用这个参数会加剧问题, 所以,一般在共享池足够大的情况下才能考虑设为true,设为true时可以减少重解析,提高命中率,加快游标的执行(空间换时间)。
这个参数一般情况不需要打开,一般情况下打开对于系统性能的提升不会很大,对于parse很频繁,而且SQL执行很频繁,共享池碎片较为严重的情况,建议不要使用。当然特殊情况有特殊的用途,否则这个参数也没必要存在了。
session_cached_cursors
缺省是0,也就是不CACHE CURSOR,如果设置了SESSION_CACHED_CURSORS,某个CURSOR被频繁调用,那么当第三次被调用的时候会被CACHE,一个被 CACHE的CURSOR下次再被调用的时候,可以省去PARSE的过程,提高SQL执行的效率,这些缓存也是用LRU算法来管理的。应该注意 SESSION_CACHED_CURSORS的值不能超过OPEN_CURSORS的值。在设置SESSION_CACHED_CURSORS参数之前,首先要确定共享池的大小是否足以支持缓冲这些SQL。因为SESSION_CACHED_CURSORS是针对每个SESSION的,对于拥有几百,甚至上千个SESSION的OLTP系统,设置SESSION_CACHED_CURSORS的时候要十分注意,设置大的 SESSION_CACHED_CURSORS参数,需要比较大的共享池来支持,如果调整了这个参数后出现共享池空间不足的情况,调整共享池的大小或者减少SESSION_CACHED_CURSORS参数就是DBA应该进行的操作
cursor_sharing
定义CURSOR共享的模式,EXCAT(精确),FORCE(强制),SIMILAR(类似),如果采用缺省的(精确),那么系统不自动合并和共享CURSOR,只有书写完全一致的CURSOR才能共享。如果设置为SIMILAR,那么SQL PARSE的时候会做PEEKING,如果觉得是可以共享的,那么就共享这个SQL,Oracle自动会将非绑定变量转换为绑定变量。要注意的是,如果某个WHERE条件里的字段存在柱状图,那么PEEKING过程会认为这个SQL的共享是不安全的,那么将不共享这个SQL,此时这个CURSOR会产生一个子CURSOR,形成一个新的版本。这种情况下,只有非绑定变量的值是相同的,PARSER才认为共享是安全的,不产生新的VERSION。如果设置为 FORCE,和SIMILAR类似,会将非绑定变量转为绑定变量,和SIMILAR不同的是,PARSER强行认为共享是安全的,因此不会理会柱状图的信息,直接共享该CURSOR。
CURSOR_SHARING的设置,最佳建议是用精确,在开发过程中,该用绑定变量的地方用绑定变量,不该用的地方不用(什么时候不该用呢?),实在不行,用SIMILAR,但是使用非缺省值的情况,需要查找是否存在BUG,尽早打补丁,另外要测试应用,某些SQL在某些版本使用绑定变量的情况下会出错(不是BUG),FORCE的BUG比较多,更要做好测试。
SQL语句分析分为软分析和硬分析两种。减少软分析和硬分析,特别是减少硬分析,对于降低CPU的使用率有着十分关键的作用
SQL执行的时候,如果某个语句已经被缓冲了,那么这个SQL就不需要进行分析,可以直接执行,因此保证SQL能够在缓冲区中长
时间存在将可以减少SQL分析的发生。有2个参数可以控制SQL在SESSION缓冲池中的时间长短:OPEN_CURSORS和SESSION_CACHED_CURSORS。
那怎样来调整这两个参数呢?检查目前SESSION_CACHED_CURSORS和OPEN_CURSORS的使用率情况
select session_cached_cursors parameter,
lpad(value, 5) value,
decode(value, 0, n/a, to_char(100 * used / value, 990) || %) usage
from (select max(s.value) used
from v$statname n, v$sesstat s
where n.name = session cursor cache count
and s.statistic# = n.statistic#),
(select value from v$parameter where name = session_cached_cursors)
union all
select open_cursors parameter,
lpad(value, 5) value,
to_char(100 * used / value, 990) || % usage
from (select max(sum(s.value)) used
from v$statname n, v$sesstat s
where n.name in
(opened cursors current, session cursor cache count)
and s.statistic# = n.statistic#
group by s.sid),
(select value from v$parameter where name = open_cursors);
查看系统级cursor的命中率,软分析和硬分析的比率
select
to_char(100 * sess / calls, 9999990.00) || % cursor_cache_hits,
to_char(100 * (calls - sess - hard) / calls, 999990.00) || % soft_parses,
to_char(100 * hard / calls, 999990.00) || % hard_parses
from
( select value calls from v$sysstat where name = parse count (total) ),
( select value hard f