为什么优化器会选择成本较高的执行计划?
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。这是额外的成本并导致索引无法使用。
这对我来说是一个反复出现的问题。我有一段时间运行良好的语句,一段时间后优化器决定选择另一个执行计划。当我只查询一个(复合)主键时,甚至会发生这种情况。
当我在 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。这是额外的成本并导致索引无法使用。