|
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?用户注册
×
一、具体的问题
很多 DBA 接到"系统突然变慢"的工单,第一反应是登录数据库看会话、看锁,折腾半天也说不清到底哪个 SQL 在拖后腿。等运维把 AWR 报告导出来,面对上百页的报告又不知道从哪一页看起,翻到最后也没找到结论。本文要解决的就是这个具体问题:拿到一份 AWR 报告后,按什么顺序读、重点看哪几个部分,才能在三五分钟内把"元凶 SQL"圈出来,并且能跟开发说清楚"改哪里、为什么"。
二、核心原理
先搞清楚 AWR 到底是什么。AWR 是 Oracle 内置的自动负载信息库,它每隔 60 分钟自动抓一次数据库运行快照,记录当时的等待事件、SQL 统计、会话信息、系统参数等,默认保留 8 天。所谓"读 AWR",本质就是取两个快照之间的数据变化,看这段时间里数据库把时间花在了哪里。
读 AWR 报告必须先抓一个总指标:DB Time 和 Elapsed Time 的对比。Elapsed Time 是报告覆盖的实际时长,DB Time 是所有会话消耗 CPU 时间和等待时间之和。如果 DB Time 明显大于 Elapsed Time,说明这段时间数据库的资源被大量争抢,确实"忙不过来",值得深入排查;如果两者差不多甚至 DB Time 很小,说明数据库本身很闲,慢的根因多半在应用端或网络,别在数据库里白费力气。
抓住这个总指标后,报告里最该看的就三块:
第一块是 Load Profile,它是一分钟级的平均值,重点看每秒事务数、每秒逻辑读、每秒物理读几个数。物理读长期偏高,基本可以断定有 SQL 在反复扫描大对象,IO 成了瓶颈。
第二块是 TOP 5 Timed Events,也就是等待事件排行。DB CPU 排第一说明 CPU 忙,根因多半是 SQL 低效(缺索引、全表扫);db file sequential read 高说明单块 IO 慢,往存储和索引上查;log file sync 高说明提交太频繁,往批量提交上改。
第三块是 SQL Statistics 里的"SQL ordered by Elapsed Time",这是直接判案的清单。注意区分两种人:一种是单次执行特别慢的(Elapsed 大、Executions 小),这种 SQL 值得逐条分析执行计划;另一种是单次不快但被执行了几十万次的,这种要抓总量,改一条语句收益最大。AWR 报告只给 Top N(默认 5 或 10),实际排查建议放宽到 20 条再看。
三、实例参考(动手步骤)
下面以一套 19c 测试库为例,走一遍"从生成报告到锁定元凶 SQL"的完整流程。
第一步,确认快照。先用下面这条查询看系统里已有哪些快照,挑出你要分析的时间段对应的起止快照号:
- SELECT snap_id, TO_CHAR(begin_interval_time,'MM-DD HH24:MI') AS begin_time
- FROM dba_hist_snapshot
- WHERE begin_interval_time > SYSDATE - 3
- ORDER BY snap_id;
复制代码
假设挑出 220 和 226 两个快照,接下来在 SQL*Plus 里执行报告脚本:
- @?/rdbms/admin/awrrpt.sql
复制代码
按提示依次输入:报告格式选 html(方便浏览器里搜索)、天数选 1、起始快照填 220、结束快照填 226、输出文件名给个 awr_0820.html。生成完用浏览器打开,直接搜索"SQL ordered by Elapsed Time"跳转过去。
第二步,从 SQL ordered by Elapsed Time 里挑嫌疑。假设排第一的 SQL 单次耗时 4 秒、执行了 12 万次,那它每天就贡献了十多个小时的执行时间,这就是首要目标。点开它的 sql_id,在报告下方找到对应的执行计划和绑定变量。
第三步,对照 TOP 5 Timed Events 验证方向。如果报告里 DB CPU 排在第一位,说明这条 SQL 是 CPU 密集型的,重点看执行计划里有没有全表扫描;若等待事件里 db file sequential read 排前面,则重点看索引路径是否缺失。
第四步,如果想立刻复核,用 v 视图实时捞一下当前库里的 TOP SQL(这条查询只读、无副作用):
- SELECT sql_id, ROUND(elapsed_time/1000000,1) AS elapsed_s,
- executions, ROUND(elapsed_time/1000000/NULLIF(executions,0),3) AS avg_s
- FROM v$sql
- WHERE executions > 0
- ORDER BY elapsed_time DESC
- FETCH FIRST 10 ROWS ONLY;
复制代码
第五步,前后对比验证。定位后给 SQL 对应的查询补上合适索引(或改写写法),隔一两天再生成一份同时段的 AWR,对比同一 sql_id 的 Elapsed Time 与物理读数量。Elapsed 降下来、TOP 5 等待事件里不再有相关条目,就说明改动有效,可以把结论写进变更记录。
四、实操检查清单
- 拿到报告先看 DB Time 与 Elapsed Time 的比值,确认瓶颈在数据库内部而非应用侧。
- 按 Load Profile 里的物理读指标,判断是否存在 IO 型压力。
- 依次核对 TOP 5 Timed Events,把等待事件与 SQL 层结论对应起来。
- 用 SQL ordered by Elapsed Time 列表,区分"单次慢"与"次数多"两类 SQL。
- 对嫌疑 SQL 点击 sql_id 查看执行计划,确认是否存在全表扫描或缺失索引路径。
- 优化后生成同时段 AWR 做前后对比,用数据确认收益。
- 把每次排查的报告文件名、快照号、结论归档,便于日后趋势对比。
|
|