AWR报告是Oracle数据库性能诊断的核心工具,需用高权限用户通过SQL*Plus执行@?/rdbms/admin/awrrpt生成,重点分析Report Summary、Top 5 Timed Events及SQL Statistics页,并结合动态视图交叉验证。

Oracle数据库运行缓慢时,AWR报告不是“可选工具”,而是最接近真相的诊断入口——它自带时间窗口、自动聚合、跨实例对比能力,比实时视图更稳定,比手工查 v$session 更系统。
怎么生成AWR报告(SQL*Plus命令行方式)
必须用有 SELECT_CATALOG_ROLE 权限的用户(如 sys 或 system)登录,否则会报 ORA-01031: insufficient privileges。生成过程不耗时,但依赖上一个快照是否已采集(默认每小时一次,需确认 DBA_HIST_SNAPSHOT 中有足够间隔的快照)。
执行以下三步:
- 在 SQL*Plus 中运行
@?/rdbms/admin/awrrpt(注意是@,不是START) - 按提示选择报告类型:
1表示文本格式(推荐首次使用),2表示HTML(适合分享) - 输入起止快照 ID(可用
SELECT MIN(snap_id), MAX(snap_id) FROM dba_hist_snapshot WHERE begin_interval_time > SYSDATE - 1;快速查最近24小时范围)
生成后文件默认输出到当前目录,名字类似 awrrpt_1_12345_12346.txt。别跳过“指定数据库ID”环节——RAC环境里漏选会只出单实例数据,掩盖跨节点争用问题。
重点看AWR报告里的哪几页
一份标准AWR报告约30页,真正需要盯住的就前5页和“SQL Statistics”部分。其他页面(如Instance Activity Stats)只有在做容量建模时才需细读。
- Report Summary:先扫 CPU、DB Time、DB CPU 占比。如果 DB Time 远高于 DB CPU(比如 DB Time=1200s,DB CPU=200s),说明大量时间花在等待上,不是CPU瓶颈,得往下翻“Top 5 Timed Foreground Events”
-
Top 5 Timed Foreground Events:这是核心线索页。常见高危项包括
log file sync(提交太慢,检查 COMMIT 频率和日志写入路径)、enq: TX - row lock contention(行锁冲突,查v$lock和阻塞链)、db file sequential read(单块读多,通常是索引缺失或绑定变量窥探失效) -
SQL Statistics → SQL ordered by Elapsed Time:这里列出实际执行耗时最长的SQL。注意区分
Elapsed Time和CPU Time—— 若前者远大于后者,大概率卡在I/O或锁;若两者接近,才是真·计算密集型SQL,该看执行计划
别被“SQL ordered by Gets”迷惑——逻辑读高不等于性能差,可能是缓存命中好;而“SQL ordered by Disk Reads”才是真正IO压力源,单条超10万次磁盘读必须处理。
为什么AWR报告有时“看不出问题”
不是报告不准,是采样窗口和问题持续时间不匹配。典型场景有:
- 问题只发生在某几分钟高峰(比如每小时整点批量JOB),但AWR默认粒度是1小时,快照刚好错过峰值。此时要手动用
DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT打快照,再生成自定义窗口报告 - 应用用了连接池且短连接频繁,
v$sql中SQL被反复硬解析,但AWR中这些SQL因执行次数少、未进Top N而隐身。此时要查DBA_HIST_SQLSTAT的PARSE_CALLS和EXECUTIONS比值,比值>5 就有问题 - RAC环境中某节点负载突增,但AWR默认汇总所有实例。必须在生成报告时选“Single Instance”并指定
inst_num,否则平均化会掩盖局部热点
AWR本身不保存原始SQL文本(只存 sql_id),如果报告里看到一堆 SQL_ID: 0xabc123 却看不到语句,说明对应SQL已被刷出共享池——这时得立刻查 v$sqlarea 或用 DBMS_XPLAN.DISPLAY_CURSOR('sql_id') 抓最后执行计划。
生成后必须做的交叉验证动作
AWR是静态快照,必须搭配动态视图才能闭环。生成完报告,立刻执行:
- 对报告中 Top SQL 的
sql_id,运行SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('sql_id', NULL, 'ALLSTATS LAST')),重点看A-Rows(实际返回行数)是否远小于E-Rows(预估行数),偏差超10倍说明统计信息过期 - 如果 Top Wait 是
log file sync,马上查SELECT * FROM v$sysstat WHERE name IN ('redo writes','redo write time');算出平均每次写日志耗时(单位毫秒),超过10ms基本可判定存储写入慢 - 发现高
db file scattered read,不要直接加索引——先查SELECT owner, segment_name, segment_type FROM dba_extents WHERE file_id = X AND block_id BETWEEN Y AND Z(X/Y/Z从等待事件中提取),确认是不是全表扫描真正在扫大表,还是误读了临时段
AWR不是终点,是把模糊的“慢”翻译成具体的“谁在等什么、等了多久、为什么等”的第一份翻译稿。真正难的从来不是生成报告,而是读懂它没明说的上下文——比如同一SQL在不同快照里 Elapsed Time 波动剧烈,往往不是SQL问题,是底层存储抖动或内存压力导致的缓冲区淘汰加剧。



















