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

时间:2010-02-04 00:12:06

标签: oracle optimization indexing

可以使用任一语句

创建两列的索引
create index foo_ix on foo(a,b);
create index foo_ix on foo(b,a);
  1. 这对使用索引的操作(运行时)特性有何影响?

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

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

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

  5. 简而言之,我先放入哪一栏是否重要?

4 个答案:

答案 0 :(得分:22)

  1. 如果ab都有1000个不同的值,并且总是一起查询它们,那么索引中列的顺序并不重要。但是,如果a只有10个不同的值,或者您的查询只使用其中一个列,那么它确实很重要;在这些情况下,如果列排序不适合查询,则可能不会使用索引。
  2. 具有最小不同值的列应该是第一个,而具有最多不同值的列应该是最后一个。这不仅最大化了索引的效用,还增加了索引压缩的潜在收益。
  3. 列的数据类型和长度会对我们从索引压缩获得的返回产生影响,但不会影响索引中列的最佳顺序。
  4. 首先排列最不具选择性的列,最后选择最具选择性的列。在带有柱的连接引线的情况下,该柱更可能单独使用。
  5. 2.和3.的一个潜在例外是DATE列。由于Oracle DATE列包含时间元素,因此它们可能每天具有86400个不同的值 。但是,数据列上的大多数查询通常只对day元素感兴趣,因此您可能只想考虑计算中不同天数。虽然我怀疑它不会影响相对选择性但只有少数情况。

    编辑(回应Nick Pierpoint的评论)

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

    1. 索引压缩
    2. 索引略读
    3. 当知道当前插槽中的值与前一个插槽中的值相同时,这些都可以发挥作用。因此,我们可以通过最小化值变化的次数来最大化这些技术的回报。在以下示例中,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
      

      大多数选择性列引导......

      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)中的18个相比,(B, A)也有20个可跳过的广告位。更广泛的差异将导致索引压缩的ROI更高或者从Index Skip读取中获得更好的效用。

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


        

      “我想如果你有一个高度选择性的第一个索引,那么 - 来自a   绩效观点 - 你最好把它放在第一位。“

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

      当我们有:

      时,多列索引最有用
      • 两列或多列中等选择性,
      • 经常在同一查询中使用。

答案 1 :(得分:5)

但根据Oracle本身,最好先将基数列为最高的列:

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

订购综合指数的关键

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

答案 2 :(得分:4)

您可以在此处找到一些问题的答案:Index Skip Scan – Does Index Column Order Matter Any More? (Warning Sign)

答案 3 :(得分:3)

  1. 如果一个列单独使用在一个     查询Oracle将使用更少     高效的跳过扫描索引访问     路径,如果它不是前导列     在索引中
  2. 取决于     各自的选择性     列
  3. 没有
  4. 我会查看涉及索引中列的查询,并按照查询次数最多的方式在索引中排名