能,AWR Compare Period报表通过对比两时段SQL的Elapsed Time、Buffer Gets、Disk Reads等指标变化率及执行计划差异,可精准识别性能退化SQL。
AWR Compare Period报表能直接看出SQL性能退化吗
不能直接标出“退化”二字,但它是目前 oracle 12c 中最接近“自动对比性能变化”的官方手段。关键在于它不比较单条 sql 的绝对耗时,而是对比两个时间段内 db time、sql id 的相对贡献变化——性能退化的 sql 往往在“top sql by db time”或“sql ordered by elapsed time”中,后一周期的排名显著上升、执行次数未增但平均耗时翻倍、或 buffer_gets/disk_reads 暴涨。
生成AWR Compare Period报表前必须确认的3件事
漏掉任意一项,报表就可能掩盖真实退化点:
- 两个快照区间(A 和 B)必须覆盖相同业务时段(例如都是工作日早高峰 9:00–10:00),否则对比无意义;
- 确保 AWR 保留策略足够长——默认 8 天,若想对比上周同一时段,需提前调大
retention(用DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS); - 检查是否启用了
STATISTICS_LEVEL = TYPICAL或ALL,若为BASIC,v$sqlstats和 AWR 中的 SQL 统计将严重缺失,报表里看不到具体 SQL。
从Compare Period报表里定位退化SQL的实操路径
别只盯着“Top 10 SQL”表格——退化常藏在细节差异里:
- 先看 “SQL ordered by Elapsed Time” 表格,对比两列的
Elapsed Time (s):如果某sql_id在 B 周期的值是 A 周期的 2.5 倍以上,且Executions变化不大(±10% 内),基本可判定退化; - 再查同一
sql_id在 “SQL ordered by Buffer Gets” 中的Buffer Gets增幅——若增幅远高于Elapsed Time增幅(比如 Buffer Gets +400%,Elapsed +80%),说明执行计划变差,可能走了全表扫描; - 重点核对 “SQL ordered by Disk Reads”:若某 SQL 的
Disk Reads在 B 周期突增 10 倍,而Executions几乎没变,大概率是索引失效、统计信息过期或绑定变量窥视失败导致; - 右键导出该
sql_id的 AWR 报表(用awrsqrpt.sql),单独拉出两个周期的执行计划,逐行比对Plan Hash Value和访问路径(TABLE ACCESS FULLvsINDEX RANGE SCAN)。
为什么Compare Period有时会“漏掉”真实退化SQL
不是工具不准,而是数据聚合逻辑天然有盲区:
- 如果退化 SQL 执行频次太低(比如每天只跑 1 次),它根本进不了 AWR 的 Top N 排名,报表里压根不显示;
- 若 SQL 使用了大量绑定变量,且不同变量值触发了不同执行计划(
PLAN_HASH_VALUE不同),AWR 会把它拆成多个sql_id统计,单个sql_id看起来平稳,实际整体已退化; - 某些短平快 SQL(
elapsed_time )即使退化 5 倍,也难突破 AWR 默认的 Top 报表阈值,需要手动查 <code>dba_hist_sqlstat并按delta_elapsed_time / delta_executions排序; - Compare Period 对比的是快照间聚合值,无法反映瞬时毛刺——比如某 SQL 在 B 周期某分钟内因锁争用卡住 30 秒,其余时间正常,报表只会显示“平均耗时略升”,看不出问题根源。
真正棘手的退化,往往不在报表首页,而在你愿意多花两分钟去查 dba_hist_sql_plan 和 dba_hist_sqlbind 的那几条记录里。











