如果我有一个表,其中a,b,c,d和pk b-tree索引按顺序排列在(a,b,c)上。我想这样查询: (1)
select b, d from table
where a = :p1
and c = :p2
即。缺少b列上的where子句以完美地利用索引。现在b列只能有几个可能值中的一个(20个唯一),但c(和a)可以有很多(100 000' s)。我认为将查询重写为:
会更有效(2)
select /*+USE_NL(table)*/ b, d from table
where a = :p1
and b IN (<allPossibleValues>)
and c = :p2
但是我还没有能够找到任何oracle文档来解释当复合索引中缺少非前导列时,(1)中的范围扫描是如何工作的。所有来源似乎只涵盖缺少前导列的情况。这些消息来源建议使用像这样的跳过扫描:
(3)
select /*+INDEX_SS(table <theIndex>)*/ b, d from table
where a = :p1
and c = :p2
当缺少的列不是前导列而是第二个(b)时,这是否有效。正如我所说的,我发现解释跳过扫描的所有来源都缺少前导列。查询(2)和/或(3)会比查询(1)更好。
答案 0 :(得分:0)
在开始过早优化之前,请检查解释计划以及生产环境中原始查询的性能。
Oracle查询优化器非常擅长选择正确的计划。根据表的大小,它可能会选择完整的索引扫描(我猜这个表有很多行可以实现)或索引范围扫描。
如果Oracle未能选择性能良好的计划,那么您可以开始优化。