awrsqrpt.sql生成的AWR报告不支持直接diff,因其输出为非结构化、人眼友好型文本,含动态格式和终端依赖;真正支持差异分析的是awrddrpt.sql,它在数据库内归一化计算两个快照区间的原始统计值并输出带delta和百分比的稳定结构化报告。
awrsqrpt.sql 生成的 AWR 报告不支持直接 diff
很多人以为 awrsqrpt.sql 输出的是标准文本报告,拿两个文件用 diff 或 excel 对比就能看出性能差异——实际不行。这个脚本本质是调用 sql*plus 格式化输出,含大量动态换行、空格对齐、页眉页脚,甚至会因终端宽度不同导致同一报告两次生成内容不一致。awrsqrpt.sql 的输出不是结构化数据,而是“人眼友好型”报表,机器难解析。
- 它不输出 SQL ID 列表、执行次数、逻辑读等原始指标的纯数值行,而是混排在段落里(比如 “SQL ordered by Elapsed Time” 下面才是表格)
- 两次运行即使参数完全一样,
SQL*Plus自动折行可能让某行被拆成两行,diff误报大量“差异” - Oracle 官方也从不承诺该脚本输出具备可比性;它只用于单次人工诊断
真正能做 AWR Diff 的是 awrddrpt.sql
awrddrpt.sql 是 Oracle 官方提供的唯一支持跨时段对比的 AWR 报告生成脚本,全称 AWR Difference Report。它不是简单拼两个 awrsqrpt,而是在数据库内直接拉取两个快照区间(比如昨天 10–11 点 vs 今天 10–11 点)的原始统计值,做归一化计算后生成差异项(如“逻辑读增长 +23%”、“硬解析多出 187 次”)。
- 必须用 SQL*Plus 连接目标库执行:
@?/rdbms/admin/awrddrpt.sql - 交互过程要输两次时间范围:先输“基线(baseline)”快照 ID 范围,再输“比较(comparison)”快照 ID 范围
- 输出仍是文本,但所有关键指标都带明确 delta 值和百分比,且每类统计(DB Time、SQL、Wait Events)单独成节,结构稳定可 grep
- 注意:两个区间必须属于同一个数据库(
dbid),且不能跨实例(RAC 需指定inst_num)
想自动化比对?别 parse awrsqrpt,改用 DBA_HIST_* 视图
如果需要写脚本定期提取“TOP 5 SQL 逻辑读变化”,硬解析增长趋势这类指标,awrsqrpt.sql 和 awrddrpt.sql 都不适合——它们是交互式工具,不返回结构化结果集。正确路径是直接查历史视图:
-
DBA_HIST_SQLSTAT存每个 SQL 在各快照区间的执行统计(buffer_gets_delta,executions_delta) -
DBA_HIST_SNAPSHOT用来确认快照时间、是否完整(status = 0) - 典型做法:用两个
snapshot_id区间做子查询,算差值并排序,例如:SELECT sql_id, SUM(buffer_gets_delta) AS bg_delta FROM dba_hist_sqlstat s JOIN dba_hist_snapshot sn ON s.snap_id = sn.snap_id WHERE sn.snap_id BETWEEN 12345 AND 12346 GROUP BY sql_id ORDER BY bg_delta DESC FETCH FIRST 5 ROWS ONLY;
- 注意时区:视图中
begin_interval_time是数据库时区,不是本地 shell 时区;脚本中别用SYSDATE - 1直接算,要用DBTIMEZONE对齐
awrddrpt 输出里最常被忽略的陷阱
awrddrpt.sql 看似省事,但默认行为埋了几个坑,不注意会导致结论错位:
- 默认只对比“Top 30 SQL”,不是全部;如果问题 SQL 排名第 32,它根本不会出现在报告里——需在交互中把 “Number of Top N SQL to report” 改成 100 或 0(0 表示不限)
- 等待事件对比默认按“总等待时间”排序,但有时“等待次数暴涨 + 平均等待变短”更关键,这种模式会被掩盖;得手动加条件查
DBA_HIST_SYSTEM_EVENT - 报告末尾的 “Instance Activity Stats” 差异是绝对值,但像
session logical reads这种累计值,若两个区间时长不同(比如一个 3600 秒,一个 3598 秒),直接比 delta 会误导;应换算成 per-second rate 再比
真正的差异分析从来不在报告格式里,而在你选哪两个快照、是否排除了维护窗口、有没有核对 DBA_HIST_SNAPSHOT.status 是否为 0。这些细节没对齐,再漂亮的 diff 也没意义。


















