in_hard_parse是硬解析瓶颈的直接信号,因其为实时采样标记,仅当会话正构建解析树、生成执行计划并写入library cache时置为Y,不依赖执行完成、无聚合延迟、不受缓存刷新影响,每秒采样直接捕获“正在发生”的CPU密集型操作,且必伴随latch: library cache或shared pool争用。
为什么in_hard_parse是硬解析瓶颈的直接信号
in_hard_parse列不是统计值,而是实时采样标记:只要会话当前正处在硬解析阶段(即构建解析树、生成执行计划、写入library cache),该列为y。它不依赖sql执行完成、不经过聚合、不被缓存刷新影响——每秒一次的采样直接捕获“正在发生”的cpu密集型操作。
常见误判是只看v$sql里的parse_calls或loads累计值,但这些数字滞后且无法区分“此刻是否卡在解析上”。而in_hard_parse = 'Y'意味着Oracle内核正在争抢latch: library cache或latch: shared pool,CPU周期正被编译逻辑吞噬,不是在执行SQL,也不是在等IO。
如何用in_hard_parse快速定位真实瓶颈SQL
不要查全量历史,必须加时间窗口和状态过滤:
- 只查最近10分钟:
SAMPLE_TIME > SYSDATE - 10/1440,避免ASH buffer循环覆盖导致漏掉短时尖峰 - 必须同时满足
in_hard_parse = 'Y'和session_state = 'ON CPU',排除因锁等待、网络延迟等伪硬解析 - 按
sql_id聚合后,优先看COUNT(*)高且sql_opname为SELECT或INSERT的条目——DML类硬解析往往比查询更耗资源
示例语句:
SELECT sql_id, sql_opname, COUNT(*) cnt FROM v$active_session_history WHERE in_hard_parse = 'Y' AND session_state = 'ON CPU' AND sample_time > SYSDATE - 10/1440 GROUP BY sql_id, sql_opname ORDER BY cnt DESC FETCH FIRST 5 ROWS ONLY;
in_hard_parse和in_parse的区别不能混淆
in_parse = 'Y'涵盖软解析+硬解析,干扰大;而in_hard_parse = 'Y'是硬解析的专属开关。生产环境里大量绑定变量使用正常时,in_parse可能持续为Y(软解析快),但in_hard_parse几乎不出现。
关键差异点:
- 软解析也会触发
in_parse = 'Y',但基本不占CPU、无latch争用,in_hard_parse始终为N - 当
in_hard_parse = 'Y'占比超过所有活动会话的5%,就说明硬解析已成系统级瓶颈(参考AWR中DB CPU与硬解析等待的交叉验证) - PL/SQL块内循环执行未绑定SQL时,
in_hard_parse会在每次循环首尾反复跳变,ASH采样能捕捉到这种高频抖动,而v$sql统计可能只显示1次loads
容易被忽略的采样盲区和配置影响
默认每秒采样一次,但实际生效受两个隐藏参数控制:
-
_ash_sampling_interval若被调大(如设为5000毫秒),会漏掉持续时间短于5秒的硬解析尖峰 -
_ash_enable若为FALSE,整个ASH机制停摆,in_hard_parse永远为空——检查该值应作为诊断第一步 - SGA中ASH buffer满时触发紧急刷盘(
_ash_eflush_trigger默认66%),若buffer太小(_ash_size过低),高频硬解析场景下早期采样可能被覆盖
真正难缠的问题往往不在SQL本身,而在采样是否完整、是否被参数静默关闭。确认_ash_enable = TRUE和_ash_sampling_interval = 1000,才是用好in_hard_parse的前提。


















