11

以下两个指标有什么区别吗?

  • 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
4

5 回答 5

16

是的。它们是有区别的。

复合索引IDX_IndexTables_1val1用于在 where 子句中使用该列的任何查询。

复合索引IDX_IndexTables_2val2用于在 where 子句中使用该列的任何查询。

因此,例如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 列:您可以按 surname 查找,但不能单独按 firstname 查找。

于 2009-10-11T04:38:40.250 回答
4

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

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

仅索引一个字段:

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

相同的概念适用于多列索引:

当 order 为 val1,val2

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

当 order 为 val2,val1

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

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

WHERE val1='value1' AND val2='value2' (uses index in any order)
于 2009-10-11T04:49:57.263 回答
2

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

考虑这个查询:

SELECT val1
FROM IndexTables
WHERE val1 = 'MyValue'

为了知道什么索引可能被认为是从左到右读取复合索引中的列。如果在您读取查询中的所有列之前查询中不存在该列,则不会使用该索引。

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

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

于 2009-10-11T04:47:30.013 回答
2

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

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

下面的查询将在 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

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

于 2009-10-11T06:13:53.630 回答
1

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

不过我会补充一些其他的想法......

  • (col1, col2) 索引意味着您不需要 col1 单独的索引
  • (col2, col1) 索引意味着您不需要 col2 单独的索引
  • 如果覆盖,则顺序很重要(例如 col1 上的 WHERE,SELECT col2)
  • 方向(ASC/DESC)也很重要(其他问题 1其他问题 2
于 2009-10-11T07:31:31.557 回答