AWR无法捕获突发短暂慢SQL,因其依赖1小时一次的聚合快照,不记录单次执行明细;ASH每秒采样但仅保留约60分钟数据;STATISTICS_LEVEL=TYPICAL时细粒度指标被禁用;SQL若未驻留共享池或硬解析频繁亦无法追踪。

AWR报告捕获不到突发短暂慢SQL,根本原因在于它的采样机制和默认配置不匹配这类场景——它不是“实时记录器”,而是“周期性快照汇总器”。
AWR快照间隔太长,根本抓不到ms级波动
默认1小时一次的DBA_HIST_SNAPSHOT快照,只保存该时段内聚合统计(如总物理读、平均执行时间),不保留单次SQL执行的原始耗时。一次持续800ms的慢查询,若没被v$active_session_history(ASH)在采样瞬间捕获,就彻底丢失。
- ASH每秒采样一次会话状态,但只保留最近
DBA_HIST_ASH中默认约60分钟数据(受_ash_size和内存限制) - AWR不会从ASH拉取单次执行明细;它只用
DBA_HIST_SQLSTAT里的累计值(如elapsed_time_delta)做排序 - 如果某条SQL在1小时内只执行1次且慢,但其他99次都很快,它的
Physical Reads或CPU Time均值会被拉低,排不上Top列表
STATISTICS_LEVEL设为TYPICAL时部分统计项被跳过
Oracle 11g默认STATISTICS_LEVEL=TYPICAL,已禁用部分细粒度指标采集。比如sql_id级别的行源操作耗时(如INDEX RANGE SCAN实际耗时)、单次执行的等待事件分布,这些都不进DBA_HIST_SQL_PLAN或DBA_HIST_SQLSTAT。
- 要让AWR记录更细的SQL行为,必须设为
ALL:ALTER SYSTEM SET STATISTICS_LEVEL=ALL - 但注意:
ALL会增加SYSAUX写入压力,且11g下仍不保证捕获所有短时SQL(尤其EXECUTIONS=1且未被硬解析缓存的语句) - 验证当前级别:
SELECT value FROM v$parameter WHERE name = 'statistics_level'
SQL未进入共享池或被快速老化,导致无历史计划可查
AWR依赖SQL在共享池中“活过至少一个快照周期”才能关联到DBA_HIST_SQL_PLAN。突发慢SQL常因以下原因逃逸:
- 使用了
/*+ NO_MONITORING */或cursor_sharing=force导致子游标未被完整跟踪 - 应用频繁硬解析(如未绑定变量),SQL文本微变,
SQL_ID不同,无法聚类 -
_cursor_plan_unload_time参数过小(默认300秒),或shared_pool紧张,导致执行计划在快照前就被挤出内存 - 查当前是否存在:运行
SELECT sql_id, child_number, plan_hash_value FROM v$sql WHERE sql_text LIKE '%your_pattern%',若为空,说明已老化
真正能捕获这种问题的是v$active_session_history(ASH),不是AWR。AWR缺失的,往往正是ASH里session_state = 'WAITING'且event非空的那些瞬间。别等报告生成,先查DBA_HIST_ACTIVE_SESS_HISTORY表里对应时间戳的sql_id和event——这才是定位“突然卡一下”的唯一可靠路径。


















