一、硬解析过多
硬解析过多可能有以下的原因:
1 、未使用绑定变量
这个比较好判断,通过查看 v$sqlarea 视图是否用许多相似的 sql 即可。解决这个问题最好是让应用修改业务,使用绑定变量解决问题 ( 但同时也要考虑绑定变量窥探,综合考虑 ) ,当然不得已
的情况也可以修改 cursor_sharing 的参数 (EXACT|FORCE|SIMILAR) 。
2 、子游标版本过多
可以通过查看视图 v$sql_shared_cursor 查看子游标不共享的原因,是否关闭自适应游标共享 (ACS) ,如果开启自适应游标共享的话,可能 oracle 认为有些 sql 不能共享子游标,导致子游标版本过多。
3 、共享池设置过小,导致 SQL 被频繁老化
通过瞬时 lru 链和周期 lru 链比值, flush chunk 次数和操作 chunk 次数比值判断是否过小
二、软解析过多
软解析过多就是游标没有被缓存进 PGA 中,可以通过调大 session_cached_cursors 值将软解析化为软软解析,不必担心这个值调大了会影响到内存,因为占了最大部分执行计划是可以被覆盖的。
三、软软解析过多
软软解析最主要的特点就是只有大量的 cursor pin 类型 mutex 竞争,有可能有 library cache 型 mutex 。
1 、解决第一步是要先找到造成竞争的 sql 语句,可以用 v$session 的 sid , P1 值定位, P1 值在所有 mutex 竞争里都一样时 sql 的 HASH value 值 ( 需要把从十六位转为十进制 )
2 、找到 sql 语句后在不修改语义的情况下修改 sql ,例如 machine1 机器发起的 sql 就在 sql 中加入 /*+machine1*/ , machine2 加 /*+machine2*/ ,这样他们就是两条 sql 了,会在各自会话中重新硬解析,
但他们的执行计划还是一样的。不过这样会增加内存的使用。
3 、减少解析次数
PL/SQL 代码块里,可以把解析步骤放到循环外,如果是 JDBC 这样的客户端,可以在应用服务器层面缓存游标。他们两个目的都是为了达到 " 一次解析,多次执行 " 。
