对我来说,这是一个重新出现的问题。我的语句在一段时间内运行良好,一段时间后,优化器决定选择另一个执行计划。当我查询一个(复合)主键时,甚至会发生这种情况。
当我在dba_hist_sql_plan中查找执行计划时,它显示使用主键索引的查询成本为20,执行全表扫描的查询成本为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
我已经注意到优化器仅使用主键索引中的第一列,然后执行范围扫描。但我真正的问题是:为什么优化器选择更高成本的执行计划?并不是两个执行计划同时使用,我注意到一个快照中的一个切换然后它保持这样几个小时/天。所以它不会成为绑定偷看的问题。
我们目前的解决方案是调用我们的DBA并刷新Statement Cache。但这并不是真正可持续的。
编辑: SQL看起来像这样:从X中选择*,其中X.id1 =?和X.id2 =?和X.id3 =? with(id1,id2,id3)是表上的复合主键(具有唯一索引)。
答案 0 :(得分:1)
也许这与Oracle 11g上的一个错误有关 错误18377553 :使用直方图和值估算的不良加性度> 32 BYTES
当您的数据如下:
AAAAAAAAAAAAAAAAAAAAmyvalue
AAAAAAAAAAAAAAAAAAAAsomeohtervalue
AAAAAAAAAAAAAAAAAAAAandsoon
B1234
直方图效果不佳。
解决方案是禁用主键上的直方图,所有这些都将开始顺利运行。
答案 1 :(得分:0)
最有可能的聚类因素和指数的瑕疵可能非常高。通过查询dba_indexes来检查瑕疵。如果blevel大于3,请尝试重建索引。
还要检查为主键创建的索引是否唯一。根据计划,它使用范围扫描而不是唯一扫描。很可能该指数并非独一无二。
答案 2 :(得分:0)
显然,优化程序无法正确显示有关类型转换的成本。此问题的根本原因是日期值的类型映射不正确。虽然数据库中的列是DATE类型,但JDBC类型错误地是java.sql.Timestamp。要将DATE列与Timestamp搜索参数进行比较,需要首先将表中的所有值传输到Timestamp。这是额外的成本,并使索引无法使用。