You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Oracle执行计划(Explain Plan)显示行数错误的原因是什么?

执行计划行数估算错误的原因及解决办法

这个问题的核心原因是Oracle成本优化器(CBO)使用的表和列统计信息过时了,导致它无法准确估算查询返回的行数。

具体分析:

  • 执行计划里的行数是CBO基于统计信息计算的估算值,不是实际返回行数。你在插入1200条新数据(其中200条tip_coperta='paperback')之前,表中只有4条paperback数据,而插入后没有更新统计信息,CBO依然沿用旧的统计数据,所以估算行数还是4。
  • Oracle的CBO依赖以下统计信息来估算行数:
    • 表的总行数(NUM_ROWS)
    • 列的不同值数量(NUM_DISTINCT)
    • 列值的分布频率(HISTOGRAM等)
      这些信息没有更新的话,CBO就无法知道表数据已经发生了大幅变化。

验证方式:

你可以查询以下视图确认统计信息是否过时:

-- 查看表的统计信息更新时间和总行数
SELECT num_rows, last_analyzed FROM user_tables WHERE table_name = 'CARTE';

-- 查看tip_coperta列的统计信息
SELECT num_distinct, num_nulls, last_analyzed 
FROM user_tab_col_statistics 
WHERE table_name = 'CARTE' AND column_name = 'TIP_COPERTA';

如果last_analyzed是你插入数据之前的时间,num_rows远小于实际的1207条(7+1200),那就说明统计信息确实没更新。

解决办法:

手动收集表的统计信息,让CBO获得准确的数据分布:

EXEC DBMS_STATS.GATHER_TABLE_STATS(
    ownname => '你的用户名', -- 替换为你的数据库用户名
    tabname => 'CARTE',
    estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, -- 自动选择采样比例
    cascade => true -- 同时收集索引的统计信息
);

收集完成后,再重新查看执行计划,估算的行数就会和实际情况接近了。

额外提示:

你的存储过程里每次循环都执行COMMIT,这会增加数据库的事务开销,建议改成批量提交(比如每100条提交一次),不过这和执行计划行数估算错误无关。

内容的提问来源于stack exchange,提问作者Diana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 04:04:04