oracle查询结果不一致通常源于数据快照差异或执行路径变化,而非数据本身不一致;awr虽不存查询结果,但可通过dbms_xplan.display_awr回溯历史执行计划,结合plan_hash_value、ash及统计信息分析根因。
oracle 查询结果不一致,绝大多数情况**不是数据真的“不一致”**,而是你看到的不是同一份数据快照,或执行路径导致逻辑结果差异。awr 本身不记录查询结果,但能帮你确认:执行计划是否在不同时间点发生了变化,从而间接解释“为什么同样 sql 在不同时段返回不同性能、甚至不同结果(如未加排序的 top-n 查询)”。
查不到结果 vs 结果条数对不上
这是最典型的误解来源。比如 PL/SQL Developer 里能看到数据,而 sqlplus 命令行查不到:
- 常见原因是
autocommit设置不同 —— PL/SQL Developer 默认关闭自动提交,你插入后没commit,只在当前会话可见;sqlplus 默认可能已开启或会话已断开,看不到未提交数据 - 另一个可能是连接了不同 PDB 或不同 service_name,
SELECT SYS_CONTEXT('USERENV', 'CON_NAME')可验证当前容器名 - 还有极小概率是闪回查询(
AS OF TIMESTAMP)或读一致性被显式控制,但普通 DML 场景几乎不会触发
执行计划变了,但 SQL 没动,怎么办
AWR 是唯一能回溯历史执行计划的常规手段。关键函数是 dbms_xplan.display_awr,但它需要知道 sql_id 和快照范围:
- 先用
SELECT sql_id, sql_text FROM dba_hist_sqltext WHERE sql_text LIKE '%your_keyword%'找出目标sql_id - 再查该 SQL 在不同快照间的计划差异:
SELECT * FROM TABLE(dbms_xplan.display_awr('abc123xyz', NULL, NULL, 'ALL'))—— 第二、三参数留空表示查全部快照,但实际建议限定范围,否则输出爆炸 - 注意:
display_awr返回的是文本格式计划,无法直接比对。要用脚本提取PLAN_HASH_VALUE,再按时间分组统计频次,才能看出“某计划在快照 124–126 出现,127 后消失”
AWR 显示 plan_hash_value 相同,但性能差很多
这说明执行计划结构没变,但内部行为可能严重退化:
-
PLAN_HASH_VALUE只校验计划树结构,不校验谓词推入位置、绑定变量窥探结果、临时表物化时机等细节 - RAC 环境下尤其典型:两个节点
PLAN_HASH_VALUE完全一致,但一个节点大量等待gc cr multi block request,本质是跨实例数据块传输开销,AWR 的 Top 5 Timed Events 里会暴露这点 - 此时要结合
dba_hist_active_sess_history查具体等待事件分布,不能只盯执行计划
为什么 AWR 报告里找不到那条 SQL
不是所有 SQL 都会被 AWR 捕获,有硬性门槛:
- 默认只捕获
elapsed_time > 5s或cpu_time > 5s或buffer_gets > 1000的语句(可查DBA_HIST_WR_CONTROL中的TOPNSQL设置) - 如果 SQL 执行很快但调用极频繁,单次不达标,也可能被过滤掉 —— 此时得靠 ASH(
v$active_session_history)实时抓,或开 10046 trace - 刚执行完就去查 AWR,可能还没生成快照(默认每小时一次),需确认
dba_hist_snapshot中最新snap_id是否覆盖你的时段
真正难的不是查到执行计划,而是判断哪一版计划“应该”被用 —— 统计信息陈旧、绑定变量窥探失准、自适应计划中途切换,都可能导致 AWR 里多个 plan_hash_value 并存。这时候光看 AWR 不够,得配合 dba_hist_sql_plan 的 OTHER_XML 字段反查谓词和基数估算,才能定位根因。











