AWR默认捕获前30条Top SQL,修改topnsql参数(范围1–100)仅影响后续新快照中按elapsed_time排序的SQL数量,历史快照不重算,且实际入库数取决于该周期内SQL耗时的差异化程度。
awr 默认只捕获前 30 条 top sql,不是“没抓到”,而是被 topnsql 阈值主动截断了。
为什么改了 topnsql 却看不到更多 SQL?
常见误解是“改完参数就能立刻在历史快照里看到更多 SQL”。实际不是:
-
topnsql只控制后续新生成的快照中按elapsed_time排序的 SQL 数量,已有快照数据不会重算、不会回填 - 即使设成
100,也不代表每份快照真有 100 条 SQL 入库——它只取该快照周期内elapsed_time排名前 N 的语句;如果周期内所有 SQL 耗时接近(比如大量毫秒级 OLTP 查询),可能只录了 20 条就“拉不开差距”,提前截止 -
topnsql仅影响按总耗时(elapsed_time)排序的 SQL;按cpu_time、buffer_gets、disk_reads等维度排的 Top SQL 数量由其他隐含参数控制,不随此参数变化
怎么确认当前 topnsql 设置是否生效?
执行以下查询,看返回值是否为你期望的数字:
SELECT topnsql FROM dba_hist_wr_control;
注意:必须用 SYS 或具备 ADMINISTER DATABASE TRIGGER 权限的用户执行修改。普通 DBA 用户会报权限不足错误。
修改命令示例(设为 60):
EXEC DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS(topnsql => 60);
若输入值超出范围(如 101),会报错:ORA-13541: topnsql value must be between 1 and 100
为什么设了 100 还查不到某条 SQL 的历史执行计划?
dba_hist_sql_plan 依赖 SQL 先被录入 dba_hist_sqlstat,而后者受 topnsql 控制。所以根本原因还是这条 SQL 没进快照:
- 它在对应快照周期内的
elapsed_time排名未进前 N - 它执行频次低、单次耗时短、逻辑读少,综合指标不够“突出”
- 快照间隔太长(比如 1 小时),而该 SQL 只在某几分钟内集中爆发,被平均稀释掉了
此时可考虑:手工触发快照(DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT),并在业务高峰刚结束时立即执行,提高捕获概率。
容易被忽略的关键点
topnsql 不是万能开关。它只解决“够不够多”的问题,不解决“对不对”的问题。真正决定一条 SQL 能否入库的,是它在那个快照窗口内的相对性能表现。如果你的系统全是轻量、均质、短平快的语句,再调高 topnsql 也难拉满;反过来,如果某条 SQL 偶尔慢得离谱,哪怕只执行一次,只要耗时碾压其他语句,它就大概率会被捕获——哪怕 topnsql 是默认 30。











