硬解析是oracle因共享池中无可用执行计划而被迫从头解析sql的过程,平均耗时5–20ms,高频率会显著消耗cpu;常见原因包括首次执行、绑定变量不匹配、统计信息更新、共享池压力或ddl语句等。
硬解析不是“sql写得差”,而是执行环境没准备好——共享池里找不到可复用的执行计划,oracle被迫从头解析、校验、生成、加载,这个过程平均耗时 5–20ms,100 次硬解析就吃掉 1 秒以上 cpu 时间。awr 能暴露它,但不能直接告诉你哪行代码漏了绑定变量。
看 AWR 报告里 Hard Parses 是否异常高
打开 AWR HTML 报告,跳到 Report Summary → Load Profile 表格,重点关注 Hard Parses 这一行:
- 单位是 “per second”,不是总数;超过
100就算高风险(尤其在 OLTP 系统) - 对比
Parses总数:如果Hard Parses / Parses > 0.8,说明绝大多数解析都是硬解析 - 再看
Logons:如果每秒登录数也高(> 2),可能是应用频繁重建连接,连带触发硬解析
定位具体是哪些 SQL 在硬解析
AWR 本身不存 parse 类型明细,但 DBA_HIST_SQLSTAT 里有 PARSE_CALLS 和 EXECUTIONS,比值接近 1 就是典型硬解析信号:
SELECT sql_id, sql_text,
parse_calls, executions,
ROUND(parse_calls / NULLIF(executions, 0), 2) parse_ratio
FROM dba_hist_sqltext t
JOIN dba_hist_sqlstat s USING (sql_id)
WHERE s.snap_id BETWEEN &begin_snap AND &end_snap
AND s.parse_calls > 50
AND s.executions > 0
ORDER BY parse_ratio DESC, s.parse_calls DESC;
- 结果中
parse_ratio > 0.9的 SQL,基本可以断定没重用执行计划 - 注意排除 DBA 工具类 SQL(如
SELECT * FROM v$session),它们本就不该被缓存 - 如果
sql_text里大量出现字面量(WHERE id = 123而非WHERE id = :b1),就是绑定变量缺失的铁证
确认是不是共享池压力导致的硬解析抖动
硬解析多不等于应用写得烂,也可能是共享池太小或碎片化,让已有计划被挤出内存:
- 查
v$sgastat中free memory在shared pool下是否长期低于 50MB - 运行
SELECT * FROM v$librarycache WHERE namespace = 'SQL AREA' AND gethitratio ,命中率低说明 SQL AREA 频繁失效 - 检查 AWR 的 Top 10 Timed Events:如果出现
latch: shared pool或cursor: pin S wait on X,就是硬解析争用 latch 的直接证据
真正难排查的不是“哪条 SQL 硬解析”,而是“为什么它没走软解析”——可能因为游标被 ALTER SYSTEM FLUSH SHARED_POOL 清过,也可能因为 cursor_sharing=force 导致计划被强制改写后无法复用。这些痕迹不会留在 AWR 里,得结合 alert.log 和应用部署日志交叉验证。











