Oracle:列顺序在索引中是否重要?

Mar*_*son 22 oracle indexing optimization

可以使用任一语句创建两列的索引

create index foo_ix on foo(a,b);
create index foo_ix on foo(b,a);
Run Code Online (Sandbox Code Playgroud)
  1. 这如何影响使用索引的操作(运行时)特征?

  2. 这如何影响索引的布局(物理)特征?

  3. (1)或(2)是否受列的类型/大小的影响?

  4. 创建多列索引的最佳做法是什么?

简而言之,我首先放入哪一列是否重要?

APC*_*APC 23

  1. 如果ab都有1000个不同的价值观和他们总是一起查询则列索引的顺序并不重要.但是,如果a只有10个不同的值,或者您只有一个列的查询,那么它确实很重要; 在这些情况下,如果列排序不适合查询,则可能不会使用索引.
  2. 具有最小不同值的列应该是第一个,并且具有最不同值的列最后.这不仅最大化了索引的效用,还增加了索引压缩的潜在收益.
  3. 列的数据类型和长度会影响我们可以从索引压缩获得的返回,但不会影响索引中列的最佳顺序.
  4. 首先排列具有最少选择性列的列,最后排列最具选择性的列.在带有柱的连接引线的情况下,该柱更可能单独使用.

2.和3.的一个潜在例外是DATE列.由于Oracle DATE列包含时间元素,因此每天可能有86400个不同的值.但是,数据列上的大多数查询通常只对day元素感兴趣,因此您可能只想考虑计算中不同天数.虽然我怀疑它不会影响相对选择性但只有少数情况.

编辑(回应Nick Pierpoint的评论)

引导最少选择性列的两个主要原因是

  1. 索引压缩
  2. 索引跳过读取

通过知道当前插槽中的值与前一个插槽中的值相同,这两者都起到了作用.因此,我们可以通过最小化值变化的次数来最大化这些技术的回报.在以下示例中,A有四个不同的值,B有六个.dittos表示可压缩值或可跳过索引块.

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
Run Code Online (Sandbox Code Playgroud)

最具选择性的列引线......

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
Run Code Online (Sandbox Code Playgroud)

即使在这个例子中,(A, B)也有20个可跳过的插槽(B, A).更广泛的差异将导致索引压缩的ROI更高或者从Index Skip读取中获得更好的效用.

与大多数调整启发式一样,我们需要使用实际值和实际量进行基准测试.这绝对是一种情况,数据偏差可能会对不同方法的有效性产生巨大影响.


"我认为,如果你有一个高度选择性的第一指数 - 从绩效的角度来看 - 你会把它放在第一位."

如果我们有一个高度选择性的列,那么我们应该建立一个自己的索引.避免对少数几行进行FILTER操作的额外好处不太可能被维护复合索引的开销所抵消.

当我们有以下内容时,多列索引最有用:

  • 两列或多列中等选择性,
  • 它们经常在同一个查询中使用.


小智 5

但根据Oracle本身,最好先将具有最高基数的列放在第一位:

http://docs.oracle.com/cd/B10500_01/server.920/a96533/data_acc.htm#2174

订购综合指数的关键字

如果在WHERE子句中经常使用所有键,那么在CREATE INDEX语句中将这些键从最具选择性排序到最少选择性可以最好地提高查询性能.