Oracle中如何通过AWR查看历史慢SQL的详细统计信息?

2026-04-28 22:373阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计935个文字,预计阅读时间需要4分钟。

Oracle中如何通过AWR查看历史慢SQL的详细统计信息?

相关专题

查AWR里执行时间最长的SQL用 dba_hist_sqlstat

awr快照中真正记录历史sql耗时的是 dba_hist_sqlstat,不是 v$sql(那是内存中当前缓存的)。关键字段是 elapsed_time_delta,单位微秒,需除以 1000000 转成秒。

常见错误是直接查 ELAPSED_TIME——它没做归一化,可能含多次执行叠加值;必须用带 DELTA 的列,代表该快照周期内增量耗时。

  • 筛选慢SQL:加条件 ELAPSED_TIME_DELTA / 1000000 >= 2(2秒以上)
  • 避免漏掉低频但单次极慢的SQL:别只按 EXECUTIONS 排序,优先按 ELAPSED_TIME_DELTA 降序
  • 关联SQL文本要用 dba_hist_sqltext,注意 sql_id 可能为空(硬解析失败或被老化出共享池)

从AWR报告导出Top SQL要盯住“SQL Statistics”章节

生成AWR报告(awrrpt.sql)后,翻到“SQL Statistics”部分,里面分多个子表:SQL ordered by Elapsed TimeSQL ordered by CPU TimeSQL ordered by Gets 等。最常用的是第一个。

这里每条SQL带的“Elapsed Time per Exec (s)”是真实平均值,比手工算 v$sqlarea 更可靠——因为AWR已自动过滤掉异常抖动和采样偏差。

  • 注意报告时间范围:默认是最近两个快照,可用 awrrpti.sql 指定自定义起止 snapshot_id
  • 如果SQL文本被截断(显示为“….”),在报告末尾的“SQL Statements”附录里找完整文本
  • 同一 sql_id 在不同快照中可能有不同执行计划,别假设它始终走同一条路径

dbms_xplan.display_awr 看历史执行计划

v$sql 里的执行计划随时可能被刷出内存,但AWR会持久化保存快照周期内的计划。调用 dbms_xplan.display_awr 才能还原当时真实走法。

典型命令:select * from table(dbms_xplan.display_awr('your_sql_id'));。不指定快照ID时,默认取该 sql_id 最近一次出现的快照。

  • 如果返回空:说明该 sql_id 没进过AWR(可能未启用统计收集,或快照间隔太长漏采)
  • 对比当前和历史计划差异时,重点看 OperationOptions 列是否出现 TABLE ACCESS FULL ——这往往是索引失效或统计信息陈旧的信号
  • 别依赖 PLAN_HASH_VALUE 相等就认为计划一致:相同 hash 值下,Access PredicatesFilter Predicates 可能已变

为什么 dba_hist_active_sess_history 有时比AWR更准?

当某条SQL执行超长(比如卡在锁或IO上),但它在快照周期内没完成,dba_hist_sqlstat 就不会记录其耗时——AWR只统计“已完成”的SQL。这时得靠 dba_hist_active_sess_history

它按秒采样活跃会话,哪怕SQL没结束,只要在采样点处于 ACTIVE 状态,就会记一笔。查它能发现“正在发生但尚未落地”的慢查询。

  • 关键过滤条件:event = 'db file sequential read'event like '%enq:%'(锁等待)
  • 结合 SAMPLE_TIMEsql_id,可定位到具体哪一秒卡在哪条SQL
  • 缺点是数据量大、查询慢,别无限制地 SELECT *,先用时间范围和用户过滤

AWR里看慢SQL,真正的难点不在查语句,而在确认“这个慢是常态还是偶发”。同一 sql_id 在不同快照里 ELAPSED_TIME_DELTA 差几倍很常见——得交叉比对 dba_hist_sqlstatdba_hist_active_sess_historydbms_xplan.display_awr 输出,才能排除采样误差和临时阻塞干扰。

标签:Oracle

本文共计935个文字,预计阅读时间需要4分钟。

Oracle中如何通过AWR查看历史慢SQL的详细统计信息?

相关专题

查AWR里执行时间最长的SQL用 dba_hist_sqlstat

awr快照中真正记录历史sql耗时的是 dba_hist_sqlstat,不是 v$sql(那是内存中当前缓存的)。关键字段是 elapsed_time_delta,单位微秒,需除以 1000000 转成秒。

常见错误是直接查 ELAPSED_TIME——它没做归一化,可能含多次执行叠加值;必须用带 DELTA 的列,代表该快照周期内增量耗时。

  • 筛选慢SQL:加条件 ELAPSED_TIME_DELTA / 1000000 >= 2(2秒以上)
  • 避免漏掉低频但单次极慢的SQL:别只按 EXECUTIONS 排序,优先按 ELAPSED_TIME_DELTA 降序
  • 关联SQL文本要用 dba_hist_sqltext,注意 sql_id 可能为空(硬解析失败或被老化出共享池)

从AWR报告导出Top SQL要盯住“SQL Statistics”章节

生成AWR报告(awrrpt.sql)后,翻到“SQL Statistics”部分,里面分多个子表:SQL ordered by Elapsed TimeSQL ordered by CPU TimeSQL ordered by Gets 等。最常用的是第一个。

这里每条SQL带的“Elapsed Time per Exec (s)”是真实平均值,比手工算 v$sqlarea 更可靠——因为AWR已自动过滤掉异常抖动和采样偏差。

  • 注意报告时间范围:默认是最近两个快照,可用 awrrpti.sql 指定自定义起止 snapshot_id
  • 如果SQL文本被截断(显示为“….”),在报告末尾的“SQL Statements”附录里找完整文本
  • 同一 sql_id 在不同快照中可能有不同执行计划,别假设它始终走同一条路径

dbms_xplan.display_awr 看历史执行计划

v$sql 里的执行计划随时可能被刷出内存,但AWR会持久化保存快照周期内的计划。调用 dbms_xplan.display_awr 才能还原当时真实走法。

典型命令:select * from table(dbms_xplan.display_awr('your_sql_id'));。不指定快照ID时,默认取该 sql_id 最近一次出现的快照。

  • 如果返回空:说明该 sql_id 没进过AWR(可能未启用统计收集,或快照间隔太长漏采)
  • 对比当前和历史计划差异时,重点看 OperationOptions 列是否出现 TABLE ACCESS FULL ——这往往是索引失效或统计信息陈旧的信号
  • 别依赖 PLAN_HASH_VALUE 相等就认为计划一致:相同 hash 值下,Access PredicatesFilter Predicates 可能已变

为什么 dba_hist_active_sess_history 有时比AWR更准?

当某条SQL执行超长(比如卡在锁或IO上),但它在快照周期内没完成,dba_hist_sqlstat 就不会记录其耗时——AWR只统计“已完成”的SQL。这时得靠 dba_hist_active_sess_history

它按秒采样活跃会话,哪怕SQL没结束,只要在采样点处于 ACTIVE 状态,就会记一笔。查它能发现“正在发生但尚未落地”的慢查询。

  • 关键过滤条件:event = 'db file sequential read'event like '%enq:%'(锁等待)
  • 结合 SAMPLE_TIMEsql_id,可定位到具体哪一秒卡在哪条SQL
  • 缺点是数据量大、查询慢,别无限制地 SELECT *,先用时间范围和用户过滤

AWR里看慢SQL,真正的难点不在查语句,而在确认“这个慢是常态还是偶发”。同一 sql_id 在不同快照里 ELAPSED_TIME_DELTA 差几倍很常见——得交叉比对 dba_hist_sqlstatdba_hist_active_sess_historydbms_xplan.display_awr 输出,才能排除采样误差和临时阻塞干扰。

标签:Oracle