为什么优化器会选择成本较高的执行计划?

why does the optimizer choose the higher cost execution plan?

这对我来说是一个反复出现的问题。我有一段时间运行良好的语句,一段时间后优化器决定选择另一个执行计划。当我只查询一个(复合)主键时,甚至会发生这种情况。

当我在 dba_hist_sql_plan 中查找执行计划时,它显示使用主键索引的查询成本为 20,执行完整 table 扫描的查询成本为 270。

plan_hash_value Operation        Options              Cost  Search_Columns

2550672280  0   SELECT STATEMENT                       20
2550672280  1   PARTITION HASH   SINGLE                20
2550672280  2   TABLE ACCESS     BY LOCAL INDEX ROWID  20
2550672280  3   INDEX            RANGE SCAN            19                1

3908080950  0   SELECT STATEMENT                      270
3908080950  1   PARTITION HASH  SINGLE                270
3908080950  2   TABLE ACCESS    FULL                  270

我已经注意到优化器只使用主键索引中的第一列,然后进行范围扫描。但我真正的问题是:为什么优化器会选择成本较高的执行计划?并不是同时使用了两个执行计划,我注意到一个快照中的一个切换,然后它在多个 hours/days 中保持这种状态。所以这不可能是绑定偷看的问题。

我们目前的解决方案是我打电话给我们的 DBA,他刷新语句缓存。但这并不是真正可持续的。

编辑: SQL 看起来像这样: select * from X where X.id1 = ?和 X.id2 =?和 X.id3 =? 其中 (id1,id2,id3) 是 table.

上的复合主键(具有唯一索引)

很可能聚类因子和索引的 blevel 非常高。通过查询 dba_indexes 检查 blevel。如果 blevel 大于 3,请尝试重建索引。

还要检查为主键创建的索引是否唯一。按照计划,它使用范围扫描而不是唯一扫描。索引很可能不是唯一的。

可能与 Oracle 11g 上的一个错误有关。
错误 18377553:直方图和值 > 32 字节的基数估计不佳

当您的数据如下:

AAAAAAAAAAAAAAAAAAAAmyvalue
AAAAAAAAAAAAAAAAAAAAsomeohtervalue
AAAAAAAAAAAAAAAAAAAAandsoon
B1234

直方图效果不佳。

解决方案是在主键上禁用直方图,一切都会开始顺利进行。

显然优化器没有正确显示有关类型转换的成本。此问题的根本原因是日期值的类型映射不正确。虽然数据库中的列是 DATE 类型,但 JDBC 类型不正确 java.sql.Timestamp。要将 DATE 列与 Timestamp 搜索参数进行比较,table 中的所有值都需要先传输到 Timestamp。这是额外的成本并导致索引无法使用。