同一sql_id在升级前后AWR中出现多个plan_hash_value即表明执行计划已真实变化,需通过DBA_HIST_SQLSTAT和DISPLAY_AWR对比谓词、cardinality预估及Note区差异确认根因。

查同一sql_id在升级前后AWR中是否出现多个plan_hash_value
执行计划是否真变了,不能靠感觉或报告里Top SQL排序变化来判断。AWR是唯一能回溯真实执行路径的来源,关键看DBA_HIST_SQLSTAT里同一sql_id是否在两个时间窗口内对应多个plan_hash_value。
运行这个查询(把'abc123xyz'换成你的SQL ID):
SELECT plan_hash_value, COUNT(*), MIN(sample_time), MAX(sample_time)
FROM dba_hist_sql_plan p
JOIN dba_hist_sqlstat s USING (sql_id, plan_hash_value)
WHERE sql_id = 'abc123xyz'
AND sample_time BETWEEN TO_DATE('2026-08-10 00:00', 'YYYY-MM-DD HH24:MI')
AND TO_DATE('2026-08-15 23:59', 'YYYY-MM-DD HH24:MI')
GROUP BY plan_hash_value
ORDER BY MIN(sample_time);- 返回多行 → 升级后计划已漂移,继续比对细节
- 只有一行 → 性能下降大概率与执行路径无关,先排查硬解析、I/O抖动或内存压力
-
DBA_HIST_SQL_PLAN默认每sql_id最多存1000行计划,高频SQL可能被截断;空结果不等于没历史计划,得确认dba_hist_snapshot里快照确实存在
用DISPLAY_AWR对比谓词、cardinality预估和Note区差异
同一个plan_hash_value不代表性能一致。统计信息失真会导致优化器对cardinality预估严重偏离(比如预估100行,实际返回50万),进而引发嵌套循环膨胀、临时表空间耗尽等问题。
必须用DBMS_XPLAN.DISPLAY_AWR带'ADVANCED'参数查两份报告:
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_AWR('abc123xyz', NULL, NULL, 'ADVANCED'));- 重点比对:Predicate Information里实际过滤条件是否一致(尤其
LIKE、IN、绑定变量位置) - 看Rows(Estim)列——同一节点预估行数在升级前后是否差3倍以上?差得越多,越可能是统计信息或直方图问题
- Note区有没有
SQL plan baseline used?升级后消失,说明基线没生效;或者出现optimizer_features_enable相关提示,指向新版本CBO行为变更 - 别漏掉
+PEEKED_BINDS——它能暴露绑定变量窥探是否被禁用,这在12c+版本很常见
核对统计信息last_analyzed时间与直方图状态是否同步
升级本身不改数据,但新版本优化器对统计信息更敏感。尤其是last_analyzed时间老、关键列缺失直方图的表,在12c+或19c中更容易触发错误选择性判断。
查核心表统计信息是否过期:
SELECT owner, table_name, last_analyzed
FROM dba_tables
WHERE owner IN ('PROD')
AND last_analyzed < SYSDATE - 7;查低基数字段是否缺直方图(如状态码、类型码):
SELECT column_name, histogram FROM dba_tab_col_statistics WHERE table_name = 'ORDER_HEADER' AND owner = 'PROD' AND histogram = 'NONE';
- 别只看
last_analyzed,要结合数据变更频率:比如某表每天增量5%,但统计信息三个月没更新,基本可判定失真 - 直方图缺失影响远大于
last_analyzed偏老——没有直方图时,优化器会把所有值当成均匀分布,导致WHERE status = 'PENDING'这种低频值预估偏差极大 - 19c中
auto_stats_advisor_task可能自动关闭了某些表的收集,需查dba_optstat_operations确认任务是否失败
注意RAC环境和optimizer_features_enable的隐式影响
升级后CPU飙升、硬解析暴涨,常不是执行计划“变差”,而是新版本CBO特性被意外激活,比如optimizer_adaptive_features在12.1中不完善,反而让部分SQL反复重生成计划。
- RAC下必须用
GV$SQL或DBA_HIST_ACTIVE_SESS_HISTORY确认所有实例是否都走同一计划;单节点查v$sql_plan会漏掉其他节点的漂移 - 如果升级前加了
/*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.4') */才恢复性能,说明问题出在CBO行为差异,不是统计信息——这时该查optimizer_features_enable默认值是否被改写,或_fix_control是否有冲突补丁 -
DBA_SQL_PLAN_BASELINES里的ENABLED/ACCEPTED/FIXED三态必须全为YES才能稳定生效;升级后ACCEPTED=NO很常见,因为新版本演进逻辑变了
真正难的不是查出plan_hash_value变了,而是确认这个变化到底是统计信息失真、直方图缺失、基线失效,还是CBO特性升级引入的不可控行为——四者修复方式完全不同,混在一起查只会来回打转。


















