AWR报告查不到某SQL主因是topnsql参数限制其未进入快照采样,该参数仅保留每周期按elapsed_time排名前N的SQL,且修改后仅对新快照生效。
awr报告里查不到某条你确认执行过的sql,大概率不是它没跑,而是根本没被采样进快照——topnsql 参数卡住了入口。
为什么改了 topnsql 还是看不到那条SQL
最常踩的坑是以为“设成100就一定能捕获100条”,其实它只取每个快照周期内按 elapsed_time 排名前N的SQL。如果那条SQL在采样窗口内执行时间太短、逻辑读太少,或者和其它SQL性能差距不明显,就会被自然截断。
-
topnsql只控制按“总执行时间”排序的Top SQL数量,不影响按CPU、IO、buffer gets等维度排名的SQL入库 - 即使设为100,若该快照周期内活跃SQL总数不足10或全部集中在毫秒级,实际入库可能只有几条
- 修改后只对新生成的快照生效,已有快照不会回填,
DBA_HIST_SQLSTAT里查不到就是真没存 - 检查当前值:运行
SELECT topnsql FROM dba_hist_wr_control;确认是否已写入
如何确认那条SQL是否具备被捕捉的资格
不是所有SQL都进得去AWR,它得先“够格”:
- 必须在快照采集窗口(默认60分钟)内完成至少一次执行;未完成的语句不计入
- 执行时间需显著高于同批其它SQL——比如窗口内其它SQL平均耗时200ms,而你的SQL是350ms,但排不进前60,就进不了
- 避免使用字面量代替绑定变量,否则相同逻辑的SQL会被视为多条,稀释排名
- 确认该SQL没有被
sql_id重复归并失败:查v$sql中force_matching_signature是否一致,不一致说明游标未共享,进一步拉低单条统计权重
调整 topnsql 的实操要点
别只改参数,得配合验证动作一起做:
- 用
SYS或拥有ADMINISTER DATABASE TRIGGER权限的用户执行:EXEC DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS(topnsql => 80); - 立刻手动触发一次快照:
EXEC dbms_workload_repository.create_snapshot();,再等至少一个完整采集周期(比如再等60分钟) - 别查旧快照!用新快照ID生成报告:
@?/rdbms/admin/awrrpt.sql,输入刚生成的snap_id范围 - 验证是否生效:在新快照对应的
DBA_HIST_SQLSTAT中查sql_id,而不是只盯AWR HTML报告里的“Top SQL”章节——有些SQL虽未进Top列表,但只要被采样过,仍会出现在全量SQL统计页
真正难的不是调高topnsql,而是让目标SQL在那个60分钟窗口里“脱颖而出”。如果它本来就是轻量OLTP语句,再怎么调参也难挤进Top榜单——这时候该想的不是改阈值,而是用ASH(V$ACTIVE_SESSION_HISTORY)直接抓实时采样,或者开SQL Trace定向捕获。


















