Oracle数据库CPU利用率低但响应慢,问题根源在等待事件,应通过ASH查询session_state = 'WAITING'且event IS NOT NULL的样本,聚焦Top 5等待事件及其P1/P2定位具体资源瓶颈。

Oracle数据库CPU利用率不高但响应极慢,说明问题大概率不在CPU争用,而在等待事件——ASH正是定位这类“不忙却卡”的核心工具,关键要查session_state = 'WAITING'且event非空的样本,而不是盯着ON CPU。
查 WAITING 状态而非 ON CPU
CPU低但响应慢,本质是会话在等资源:锁、I/O、网络、闩锁、RAC块传输等。ASH里session_state为'WAITING'的记录才是目标,漏掉这个条件就完全跑偏。
- 必须加
WHERE session_state = 'WAITING',大小写敏感,不能写成'waiting'或'Waiting' - 排除空等待:
AND event IS NOT NULL,否则会混入SQL*Net message from client这类客户端空闲等待 - 别用
v$session实时查——它只反映当前瞬间,而ASH能回溯过去1小时(内存)或更久(归档),抓到已结束但造成卡顿的等待链
重点盯住 Top 5 等待事件及其 P1/P2
ASH中event字段直接暴露瓶颈类型,但单看事件名不够,得结合p1p2定位具体对象或资源。
-
enq: TX - row lock contention:查p2(row wait object#)对应dba_objects.object_id,确认被锁的是哪张表/索引 -
latch: cache buffers chains:看p1(latch address)是否集中,再关联current_obj#判断是不是热块在特定索引叶块 -
gc current block 2-way或gc cr block busy(RAC环境):说明跨节点块请求频繁,p2(file#)和p3(block#)可定位热点数据块物理位置 -
db file sequential read:高次数+高time_waited均值,指向单块读慢,需结合current_file#和current_block#查是否是索引分支块或高水位线附近
用 dba_hist_active_sess_history 查历史窗口(非实时)
如果问题发生在10分钟前且已平息,v$active_session_history可能已被覆盖(内存环形缓冲区满),必须切到归档视图dba_hist_active_sess_history。
- 时间条件写死:
SAMPLE_TIME BETWEEN TIMESTAMP'2026-09-30 14:20:00' AND TIMESTAMP'2026-09-30 14:25:00',避免SYSDATE - INTERVAL '5' MINUTE因时区偏差失效 - 加
WHERE session_state = 'WAITING' AND event IS NOT NULL,再按event分组计数:COUNT(*)越高,该等待越可能是根因 - 若
sql_id为空但module为'JDBC Thin Client'或action有业务标识,说明是应用层未提交事务导致锁等待,不是SQL本身问题
别忽略阻塞会话链(blocking_session)
响应慢常因一个会话持锁,其他几十个会话排队等它——ASH里blocking_session和blocking_session_serial#字段能直接串起这条链。
- 执行:
SELECT session_id, session_serial#, blocking_session, blocking_session_serial#, event, sql_id FROM dba_hist_active_sess_history WHERE sample_time BETWEEN ... AND ... AND blocking_session IS NOT NULL - 找到
blocking_session对应的最早样本,查它的sql_id和sql_plan_hash_value,大概率就是那个没提交的DML或长事务 - 注意:
blocking_session字段在v$active_session_history中可能为NULL(采样时机错过),归档视图更稳定
最易被忽略的点:等待事件本身不等于问题根源。比如enq: TX - row lock contention频发,真正原因可能是应用层未开启事务自动提交、或前端重试逻辑缺失;db file sequential read高,未必是磁盘慢,可能是索引设计导致大量回表。ASH给出的是“现象快照”,交叉验证dba_hist_sqlstat执行计划变更、v$lock当前锁状态、甚至应用日志,才能闭环。











