AWR报告要想准确定位Oracle数据库性能瓶颈,必须交叉分析DB Time/AAS、Top 5等待事件中的三列(Wait Time/Waits/A vg Wait),以及SQL Statistics里的Elapsed vs CPU、Physical Reads Per Exec等关键指标,不能只看单一数据项。

AWR报告本身不会直接告诉你“性能瓶颈在哪里”,它提供的只是某个时间窗口内的聚合统计信息。真正决定你能否定位数据库瓶颈的关键,在于是否会交叉查看三组核心数据:DB Time与AAS、Top 5等待事件中的Wait Time/A vg Wait/Waits,以及SQL Statistics里的Elapsed vs CPU Time和Physical Reads Per Exec。
先看DB Time和AAS,不要一开始就翻等待事件
DB Time高并不等于数据库一定有问题,但如果AAS(A verage Active Sessions)超过2,就需要立即重点关注。计算方法就是DB Time ÷ Elapsed Time,这两个值在报告开头的Report Summary中可以直接看到。
- 快照间隔为60分钟,
DB Time是180分钟 →AAS= 3,表示平均同时有3个会话在竞争数据库资源 AAS持续 >5(OLTP系统)或 >10(报表分析类场景)时,通常才说明排队已经成为常态AAS很低(例如0.3)但用户仍反馈数据库响应慢,大概率是单条SQL延迟高、网络波动,或应用层超时参数设置过短,而不是数据库整体性能瓶颈
分析Top 5 Timed Foreground Events时一定要交叉看三列
只看“等待占比”非常容易误判。必须同时结合Wait Time(总等待时间)、Waits(等待发生次数)、A vg Wait(平均等待毫秒数)来判断问题本质。
log file sync占比只有3%,但一小时内发生420万次、A vg Wait712 µs → 实际上说明每秒提交超过1160次,本质是事务提交粒度过细,并不是磁盘写入性能慢gc buffer busy acquire占比1.2%,但A vg Wait18 ms且只由7个活跃会话触发 → 基本可以锁定为RAC热点块争用,与系统整体负载高低关系不大- 可直接跳过所有以
SQL*Net message from client开头的空闲等待事件,除非它进入Top 3且A vg Wait异常偏高(>100ms)
查看SQL ordered by Elapsed Time时要避开伪高负载
不要只盯着Elapsed Time最高的几条SQL。AWR分析中常见的误区包括:
EXECUTIONS为0但CPU_TIME_SEC非零的SQL → 通常是统计信息未及时刷新导致,属于“伪高负载”,不要贸然优化它- 单次
Elapsed Time明显大于CPU Time→ 往往说明SQL卡在I/O等待或锁等待上,此时应进一步检查执行计划或阻塞链 Buffer Gets per Exec> 10万,但Physical Reads per Exec很低 → 可能是缓存失效、latch争用等问题,不一定是SQL语句本身有问题- 应优先关注
SQL ordered by Gets中Buffer Gets per Exec> 50000 的语句,这类SQL大概率没有走索引,或存在谓词失效问题(例如where to_char(create_time, 'yyyymmdd') = '20260409')
RAC环境下必须按实例分别查看DB Time和等待事件
应使用@?/rdbms/admin/awrrpti.sql生成per-instance报告,否则节点间负载不均衡的问题会被整体数据掩盖。例如一个实例的AAS是8,另一个只有0.5,合并报告里AAS可能只显示4.3,根本无法真实反映实例失衡情况。
gc cr block lost平均等待 >1秒 → 必须结合GV$CLUSTER_INTERCONNECT验证RAC私网延迟,不能只从SQL层面排查- 某实例
enq: TX - row lock contention的Wait Time占该实例DB Time>1% → 应立即搜索enq:相关信息,并下钻DBA_HIST_ACTIVE_SESS_HISTORY定位具体会话与对象
Load Profile并不是AWR性能分析的起点,而更适合作为验证工具,这一点在Oracle性能排查中经常被忽略。当db file sequential read占比明显上升时,首先应检查Logical Reads与Physical Reads的比值是否也同步大幅增加。如果比值基本稳定但绝对值变大,通常说明是Buffer Cache被冲刷导致,并不一定是磁盘I/O本身出现问题。
