- 如果
a 和b 都有1000 个不同的值并且它们总是一起查询,那么索引中列的顺序并不重要。但是,如果 a 只有 10 个不同的值,或者您的查询只使用其中一列,那么这很重要;在这些情况下,如果列顺序不适合查询,则可能不会使用索引。
- 具有最少不同值的列应位于第一个,具有最多不同值的列位于最后。这不仅最大限度地提高了索引的效用,还增加了索引压缩的潜在收益。
- 列的数据类型和长度会影响我们从索引压缩中获得的回报,但不会影响索引中列的最佳顺序。
- 首先排列选择最少的列,最后排列选择最多的列。在与更可能单独使用的列连接的情况下。
2. 和 3. 的一个潜在例外是 DATE 列。因为 Oracle DATE 列包含一个时间元素,它们每天可能有 86400 个不同的值。然而,对数据列的大多数查询通常只对 day 元素感兴趣,因此您可能只想在计算中考虑不同天数。虽然我怀疑它不会影响少数情况下的相对选择性。
编辑(回应 Nick Pierpoint 的评论)
选择最少的列领先的两个主要原因是
- 索引压缩
- 索引跳过读取
知道当前槽中的值与前一个槽中的值相同,这两种方法都发挥了作用。因此,我们可以通过最小化值变化的次数来最大化这些技术的回报。在以下示例中,A 有四个不同的值,B 有六个。同上表示可压缩的值或可跳过的索引块。
Least selective column leads ...
A B
--------- -
AARDVARK 1
" 2
" 3
" 4
" 5
" 6
DIFFVAL 1
" 2
" 3
" 4
" 5
" 6
OTHERVAL 1
" 2
" 3
" 4
" 5
" 6
WHATEVER 1
" 2
" 3
" 4
" 5
" 6
最具选择性的列前导...
B A
- --------
1 AARDVARK
" DIFFVAL
" OTHERVAL
" WHATEVER
2 AARDVARK
" DIFFVAL
" OTHERVAL
" WHATEVER
3 AARDVARK
" DIFFVAL
" OTHERVAL
" WHATEVER
4 AARDVARK
" DIFFVAL
" OTHERVAL
" WHATEVER
5 AARDVARK
" DIFFVAL
" OTHERVAL
" WHATEVER
6 AARDVARK
" DIFFVAL
" OTHERVAL
" WHATEVER
即使在这个简单的示例中,(A, B) 也有 20 个可跳过的插槽,而 (B, A) 有 18 个。更大的差异将在索引压缩上产生更大的 ROI,或者从索引跳过读取中产生更好的效用。
与大多数调整启发式方法一样,我们需要使用实际值和实际数量进行基准测试。这绝对是一种数据倾斜可能对不同方法的有效性产生巨大影响的情况。
“我认为如果你有一个高度选择性的第一个索引,那么 - 从一个
性能观点 - 你最好把它放在第一位。”
如果我们有一个高度选择性的列,那么我们应该为它建立一个自己的索引。避免对少数行执行 FILTER 操作的额外好处不太可能被维护复合索引的开销所抵消。
多列索引在我们有以下情况时最有用: