【发布时间】:2016-03-05 09:20:36
【问题描述】:
这对我来说是一个反复出现的问题。我有一段时间运行良好的语句,一段时间后优化器决定选择另一个执行计划。当我查询一个(复合)主键时,甚至会发生这种情况。
当我在 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,他会刷新语句缓存。但这并不是真正可持续的。
编辑: SQL 看起来像这样: select * from X where X.id1 = ?和 X.id2 = ?和 X.id3 = ? (id1,id2,id3) 是表上的复合主键(具有唯一索引)。
【问题讨论】:
-
可能有很多原因。其中一些是有效的。最常见的一种是当 exec。计划适用于其他一些模式。另一个原因可能是动态采样或性能基准。
-
SQL 在哪里?你看过自适应光标共享吗?
-
SQL 很简单。比如“select * from x where x.id1 = ? and x.id2 = ? and x.id3 = ?”
-
考虑到自适应游标共享:由于我正在从复合主键中查询确切的 3 列,因此它不会是倾斜直方图的问题。我的结果集中必须只有一行或没有行。但我猜自适应游标共享可能是一个问题,因为优化器决定只查找索引中的第一列然后进行范围扫描的奇怪行为。我可能不得不解决这个问题
-
计划是否可能不同,因为某些东西偶尔会阻止索引访问?例如,是否定期删除和重建索引? (这是一件愚蠢的事情,但它确实发生了。)
标签: oracle oracle11g sql-execution-plan sql-tuning