应直接查v$active_session_history(rac用gv$),因其每秒采样、保留原始快照,可精准定位秒级cpu尖刺;ash报告会聚合抹平瞬时抖动,且内存仅保留约1小时。

直接查 v$active_session_history,别等 ASH 报告生成
ASH 报告是聚合摘要,会把连续几秒的采样合并成“平均等待”或“总样本数”,秒级卡顿、瞬时 CPU 尖刺会被抹平。真正要抓“哪一秒 SQL 突然吃满 CPU”,必须直查 v$active_session_history(RAC 环境用 gv$active_session_history)。它每秒采样一次非空闲会话,字段如 sql_id、session_state、event、sample_time 构成一张“执行快照”,能真实还原抖动瞬间。
过滤 SESSION_STATE = 'ON CPU' 并限定最近 5 分钟
高 CPU 消耗在 ASH 中体现为大量 SESSION_STATE = 'ON CPU' 的样本,不是靠 event 字段——因为“正在算”不等于“在等”。时间范围必须动态、够窄:
- 用
SAMPLE_TIME > SYSDATE - INTERVAL '5' MINUTE,别写死时间字符串(时区/NLS 差异会导致查空) - 单实例查
v$active_session_history;RAC 必须用gv$active_session_history,否则只看到本节点 - 如果问题发生在 13:22:18,建议时间窗口放宽到 ±15 秒,避免因采样点偏移漏掉关键样本
按 SQL_ID 聚合计数,别信 V$SQL 里的文本
COUNT(*) 样本数比累计时间更稳定:短 SQL 可能在单次采样中 DELTA_TIME 为 0,但只要被采到就记 1 次。但要注意:
-
V$SQL或V$SQLAREA里可能查不到SQL_TEXT——SQL 已老化出共享池,此时得切到DBA_HIST_SQLTEXT(需 AWR 权限) - 若
DBA_HIST_SQLTEXT.SQL_TEXT显示为/* SQL Analyze(123) */,要结合program字段判断是否来自DBMS_SQLTUNE等自动任务 - 同一
SQL_ID下不同SQL_CHILD_NUMBER可能对应完全不同的执行计划,优化前先确认子游标
临时表空间/Undo 高消耗不能只盯 sql_id
写临时表空间(EVENT = 'direct path write temp')或撑爆 Undo(used_ublk > 10000)的 SQL,往往在 ASH 中不显山露水:
- 查
direct path write temp必须加GROUP BY SQL_ID, PLAN_HASH_VALUE,否则并行进程会把同一计划重复计数 - Undo 压力常表现为
session_state = 'ON CPU'+sql_opname IN ('INSERT','UPDATE','DELETE'),但sql_id是系统递归语句(如select /*+ rule */ from sys.undo$),得靠program/module定位源头 - 真要确认事务级 Undo 占用,必须立刻查
v$transaction和v$session关联,ASH 只是线索,不是证据链终点
最易被忽略的是采样窗口与保留策略的错配:v$active_session_history 默认只保留约 1 小时,且高负载下可能提前滚动丢弃。你看到“查不到”,八成不是没发生,而是时间没卡准,或者已经不在内存环形缓冲区里了。











