硬解析暴增本质是共享池碎片化与锁争用的复合故障,需结合latch miss率、free memory、request_misses及v$sql中executions=1且parse_calls>1语句综合诊断。
硬解析暴增不是“sql写得差”这么简单,而是 shared pool 内部结构被高频冲击的外在表现——当 v$latch 中 latch: shared pool 的 miss rate 持续 > 0.5%,且 v$sgastat 的 free memory 长期低于 5mb、request_misses 明显升高时,说明问题已从“语句没绑定变量”升级为“共享池碎片化+锁争用”的复合故障。
查 v$sql 中 EXECUTIONS = 1 且 PARSE_CALLS > 1 的语句
这类语句是硬解析的“真凶”,不是执行少,而是每次执行都重新解析——软解析失败后退化为硬解析。它比总硬解析数更有诊断价值。
- 执行
SELECT sql_id, sql_text, executions, parse_calls FROM v$sql WHERE executions = 1 AND parse_calls > 1 AND rownum 快速抓出高频单次执行语句 - 重点看
sql_text是否仅数字/字符串字面量不同(如WHERE id = 123vsWHERE id = 456),这是未绑定变量的典型特征 - 若应用用 Python
cx_Oracle,检查是否在循环中反复调用cursor.prepare(),而非复用已 prepare 的对象
用 v$sql_shared_cursor 定位无法共享的根因
即使写了绑定变量,也可能因环境不一致导致游标无法重用。直接查 v$sql_shared_cursor 比猜更可靠。
- 对疑似语句执行
SELECT * FROM v$sql_shared_cursor WHERE sql_id = 'xxx' AND (UNBOUND_CURSOR = 'Y' OR EXPLAIN_PLAN_CURSOR = 'Y' OR OPTIMIZER_MISMATCH = 'Y') -
OPTIMIZER_MISMATCH = 'Y'常见于optimizer_features_enable设置不一致,或会话级ALTER SESSION SET optimizer_mode被误用 -
NLS_LENGTH_SEMANTICS、NLS_SORT等 NLS 参数漂移也会触发该标记,需统一客户端与数据库端设置
别只盯 AWR 里的 Library Cache Hit Ratio
77% 的命中率本身不致命,但若叠加会话突增(如某时段活跃会话从几百飙到 4 万),就会把原本可容忍的硬解析压力放大成 latch 争用风暴。
- 查
v$active_session_history中sample_time和session_state,确认高争用时段是否伴随会话数异常峰值 - AWR 报告中 “Top 5 Timed Foreground Events” 若连续多份都出现
latch: shared pool,且占比 > 15%,必须立即干预 -
Library Cache Hit Ratio低于 90% 是预警信号,但真正危险的是Execute to Parse %持续
shared_pool_size 设多大才不碎片化?
没有安全值。设大了反而掩盖碎片问题:空闲块更分散,单个不够容纳新 cursor;设小了又频繁 LRU 清理,加剧重解析。关键看使用模式。
- 观察
v$sgastat中free memory的最小值,取其 1.2 倍作为 baseline,但前提是library cache + sql area占比长期 > 60% - 若占比长期
-
V$SHARED_POOL_ADVICE可模拟不同大小下的节省时间,但依赖STATISTICS_LEVEL = TYPICAL且近期有足够负载采样,否则预测失真
最易被忽略的一点:shared pool latch 争用往往不是孤立问题,而是硬解析 + 会话爆炸 + 碎片空闲块不足三者共振的结果。单独调大 shared_pool_size 或只加绑定变量,都可能漏掉其中一环。











