2个索引之间的差异,列以相反顺序定义

时间:2009-10-11 04:25:32

标签: sql sql-server tsql indexing composite-index

以下两个索引之间是否有任何差异?

  • IDX_IndexTables_1
  • IDX_IndexTables_2

如果有,有什么区别?

create table IndexTables (
    id int identity(1, 1) primary key,
    val1 nvarchar(100),
    val2 nvarchar(100),
)

create index IDX_IndexTables_1 on IndexTables (val1, val2)
GO

create index IDX_IndexTables_2 on IndexTables (val2, val1)
GO

5 个答案:

答案 0 :(得分:16)

是。有区别。

复合索引IDX_IndexTables_1可用于where子句中使用val1列的任何查询。

复合索引IDX_IndexTables_2可用于where子句中使用val2列的任何查询。

因此,例如IDX_IndexTables_2不能用于此查询(但可以使用IDX_IndexTables_1):

SELECT val1, val2 FROM IndexTables
WHERE val1 = some_value

但可以用于此查询:

SELECT val1, val2 FROM IndexTables
WHERE val2 = some_value AND val1 = some_other-value

考虑综合指数的方法是考虑纸质电话簿;它由surname列索引,然后是firstname列:您可以按姓氏查找,但不能单独查看名字。

答案 1 :(得分:4)

多列索引在概念上与获取所有列字段并将它们合并在一起没有什么不同 - 将结果索引为单个字段。

由于索引是b-trees,因此它们总是从左向右搜索。当您向右移动索引以完成其工作并提供有用的结果时,您必须从左侧开始搜索以配对结果。

只有一个字段已编入索引:

WHERE val1 LIKE 'myvalue%' (uses index)
WHERE val1 LIKE '%myvalue' (cannot use index)

同一概念适用于多列索引:

当订单是val1时,val2

WHERE val1='value1' (uses index)
WHERE val2='value2' (cannot use index)

当订单是val2时,val1

WHERE val1='value1' (cannot use index)
WHERE val2='value2' (uses index)

如果两个字段完全匹配,那么索引的顺序在这种情况下无关紧要。

WHERE val1='value1' AND val2='value2' (uses index in any order)

答案 2 :(得分:2)

你拥有的是综合指数。当WHERE子句未使用复合索引中的所有列时,顺序很重要。

考虑这个问题:

SELECT val1
FROM IndexTables
WHERE val1 = 'MyValue'

为了知道可以考虑从哪个索引读取复合索引中的列从左到右。如果在读取查询中的所有列之前查询中不存在该列,则不会使用该索引。

IDX_IndexTables_1(val1,val2):从左到右读取val1存在,它是我们唯一的列,因此该索引将被视为

IDX_IndexTables_2(val2,val1):此查询中不存在从左到右读取的val2,因此不会使用它。

答案 3 :(得分:2)

之前的答案描述了如何使用每个索引的第一列。 (在where子句中)。

我认为指出第二列很有用也很重要,因为它可能会提高涉及第二列的查询的性能。

以下查询将通过JUST在IDX_1上进行索引搜索来完成,从而将有价值的查找保存到基表(因为val2已经是索引的一部分)。

SELECT val2 from IndexTables where val1 = @someVal1

同样,反向索引将优化此查询:

SELECT val1 from IndexTables where val2 = @someVal2

但是,两个索引中只有一个(无关紧要)需要优化以下查询:

SELECT val1, val2 from IndexTables where val1 = @someVal1 and val2 = @someVal2

这表明,根据您的表收到的查询,可能有合法的理由同时拥有这两个索引。

答案 4 :(得分:1)

其他人回答他们不同,我同意。

我会添加一些其他的想法......

  • (col1,col2)索引表示您不需要单独使用col1索引
  • (col2,col1)索引表示您不需要单独使用col2索引
  • 如果这是覆盖的顺序(例如,col1上的WHERE,SELECT col2)
  • 方向(ASC / DESC)也很重要(Other question 1Other question 2