“SQL ordered by Elapsed Time”按总耗时(单次平均耗时×执行次数)排序,非单次最慢;应重点关注Elapsed Time per Exec (s) > 1且Executions ≤ 50的语句,并结合CPU/Elapsed比值、等待事件及ASH或v$sql等实时视图综合判断真实瓶颈。

直接看“SQL ordered by Elapsed Time”但别只看总耗时
AWR报告里最常被点开的章节是 SQL ordered by Elapsed Time,但它显示的 Elapsed Time (s) 是该SQL在快照区间内所有执行的**累计耗时**,不是单次执行时间。一条高频轻量SQL(比如每秒执行50次、每次20ms)会排在顶部,但其实并不“低效”。
实操建议:
- 优先筛出
Elapsed Time per Exec (s) > 1的语句——这才是真正单次执行慢的候选 - 对比
CPU Time (s)和Elapsed Time (s):若后者远大于前者(比如比值 > 2),说明大量时间花在等待上(I/O、锁、latch),不是SQL写得差,而是资源争用 - 留意
Executions列:如果值极小(如 1–5),但总耗时高,大概率是批处理或定时任务里的关键SQL,优化收益明确
用SQL ID反查完整语句和历史执行计划
AWR报告中SQL文本默认只截取前1000字符,WHERE条件、子查询、绑定变量名常被砍掉,光靠报告无法判断逻辑问题。
必须通过 SQL ID 向后追溯:
- 先试
v$sql:它缓存当前仍在共享池中的SQL,响应快,但可能已被老化淘汰SELECT sql_text FROM v$sql WHERE sql_id = 'abc123xyz' - 再查
dba_hist_sqltext:覆盖历史快照范围,但不保证100%存在(尤其刚执行完还没被采样进AWR的)SELECT sql_text FROM dba_hist_sqltext WHERE sql_id = 'abc123xyz' - 查历史执行计划必须用
dba_hist_sql_plan,不能只看v$sql_plan(只存当前计划)SELECT * FROM dba_hist_sql_plan WHERE sql_id = 'abc123xyz' AND plan_hash_value IN (SELECT plan_hash_value FROM dba_hist_sqlstat WHERE sql_id = 'abc123xyz')
避免踩坑:SQL ID不准、快照没覆盖、权限不足
很多人跑出空结果或报错,不是脚本问题,而是三个硬性前提没满足:
-
SQL ID大小写敏感,且对空格、换行、注释、绑定变量名完全敏感。复制时容易带入不可见字符(如\u200b),建议用HEXTORAW或从dba_hist_sqltext中确认 - 快照ID必须落在
dba_hist_snapshot实际存在的范围内:SELECT MIN(snap_id), MAX(snap_id) FROM dba_hist_snapshot—— 若SQL执行时间不在这个区间,AWR里根本没它 - 执行
_awrsqrpt.sql或查dba_hist_*视图,需要SELECT_CATALOG_ROLE或显式授予SELECT权限,仅CONNECT不够
补充手段:当AWR没捕获到,就切到ASH或实时视图
AWR默认60分钟采样一次,保留8天。如果慢SQL是偶发、瞬时、或发生在快照间隙,它大概率漏掉。
这时要立刻切换阵地:
- 查最近1小时活跃会话:
SELECT sql_id, COUNT(*) cnt FROM v$active_session_history WHERE sample_time > SYSDATE - 1/24 GROUP BY sql_id ORDER BY cnt DESC - 查当前正在执行且超5秒的SQL(需企业版+诊断包):
SELECT sql_id, sql_text, elapsed_time/1000000 sec FROM v$sql_monitor WHERE status IN ('EXECUTING', 'DONE (ERROR)') ORDER BY elapsed_time DESC - 查近期缓存中平均执行超1秒的SQL:
SELECT sql_id, ROUND(elapsed_time/executions/1000000, 3) avg_sec, executions FROM v$sql WHERE executions > 0 AND elapsed_time/executions > 1000000 ORDER BY avg_sec DESC FETCH FIRST 10 ROWS ONLY
AWR不是万能的“回放录像”,它是按固定节奏拍下的性能快照;真正要挖出低效SQL,得清楚它的边界在哪——快照粒度、保留周期、采集机制,缺一不可。


















