AWR中“SQL ordered by Elapsed Time”按总耗时(单次平均×执行次数)排序,非单次最慢;默认截断SQL前1000字符,需用DBA_HIST_SQLTEXT查完整文本,并通过DBA_HIST_SQLSTAT和DISPLAY_AWR查多版本执行计划。

AWR 报告里 SQL ordered by Elapsed Time 显示不全,不是漏数据,而是 Oracle 主动截断——默认只存、只展示 SQL 文本前 1000 字符。
SQL文本被截断导致关键谓词丢失
真实问题常藏在第 1001 位之后。比如 WHERE 子句里有 IN (SELECT ... FROM huge_table JOIN another_huge_table),被砍掉后只剩 WHERE status IN,你根本看不出它关联了几个大表,执行计划也查不准。
- 用
DBA_HIST_SQLTEXT查完整语句:SELECT sql_text FROM dba_hist_sqltext WHERE sql_id = '9pf8f5kpa8rtu'(注意:该视图可能被清理,优先查DBA_HIST_SQLSTAT关联的快照区间) - 若
sql_text为空或仍不全,说明 AWR 已自动清理原始文本,此时必须从应用日志或监听器捕获原始 SQL - Oracle 19c 默认启用
_awr_sql_text_truncate隐含参数,设为FALSE可禁用截断(需重启实例,且 SYSAUX 空间压力会明显上升)
SQL_ID 相同但执行计划不同,AWR 合并显示成一条
同一 sql_id 下,如果多个快照中 plan_hash_value 不同(比如索引失效→全表扫描),AWR 仍归为一行,只显示最后一次快照的执行计划,历史计划被掩盖。
- 查多版本计划:
SELECT plan_hash_value, executions, elapsed_time/executions/1000000 avg_sec FROM dba_hist_sqlstat WHERE sql_id = '9pf8f5kpa8rtu' AND snap_id BETWEEN 12345 AND 12346 ORDER BY avg_sec DESC - 逐个看历史计划:
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_AWR('9pf8f5kpa8rtu', NULL, NULL, 'ADVANCED')),注意输出里Note段是否出现SQL plan baseline used——没这行,说明每次都在硬解析重算 - 如果
plan_hash_value在相邻快照间跳变,且elapsed_time_max / elapsed_time_avg > 15,基本可锁定是参数化查询 + 绑定变量窥探引发的执行计划抖动
高并发轻量 SQL 被聚合后“消失”
AWR 按快照间隔(默认 60 分钟)聚合统计。一条 SQL 每 5 秒执行一次、每次耗时 8 秒,总耗时 5760 秒,但它在报告里会被摊平为 Executions = 720、Elapsed Time per Exec = 8s,排不进 Top 30;而另一条每小时只跑一次、耗时 55 秒的 SQL,反而稳居第一。
- 这种“短时尖峰型”SQL 必须绕过 AWR,直接查
V$ACTIVE_SESSION_HISTORY:SELECT sql_id, event, COUNT(*) FROM v$active_session_history WHERE sample_time > SYSDATE-1/24 GROUP BY sql_id, event ORDER BY COUNT(*) DESC - 配合
DBA_HIST_SQLSTAT查分钟级趋势:SELECT TRUNC(sample_time,'MI') minute, SUM(elapsed_time)/1000000 sec FROM dba_hist_active_sess_history WHERE sql_id = '5n1zan5dzybhx' GROUP BY TRUNC(sample_time,'MI') ORDER BY minute - 别依赖
SQL ordered by Executions排名——高频 SQL 往往在Load Profile的Execute Count里更早暴露突增
真正难处理的不是“看不到”,而是看到的那条 SQL_ID 实际对应多个逻辑差异巨大的语句——比如应用拼接了不同业务模块的 WHERE 条件,但 Oracle 因绑定变量缺失或类型不一致,无法生成统一 sql_id,最终分散在多个 ID 下,需要人工聚类比对文本特征。


















