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

发布于 2024-08-07 14:11:25 字数 377 浏览 7 评论 0原文

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

  • 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

Are there any differences between following two indexes?

  • IDX_IndexTables_1
  • IDX_IndexTables_2

If there are any, what are the differences?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

柠北森屋 2024-08-14 14:11:26

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

由于索引是 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)

A multi-column index is conceptually no different than taking all the columns fields and concatinating them together -- indexing the result as a single field.

Since indexes are b-trees they are always searched left to right. You have to begin your search from the left to pair down results as you move to the right for the index to do its job and provide useful results.

With only a single field indexed:

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

The same concept is applied for multi-column indexes:

When order is val1,val2

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

When order is val2,val1

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

If both fields are matched exactly order of indexes does not matter in that case.

WHERE val1='value1' AND val2='value2' (uses index in any order)
暗恋未遂 2024-08-14 14:11:26

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

考虑这个查询:

SELECT val1
FROM IndexTables
WHERE val1 = 'MyValue'

为了了解可能考虑使用什么索引,请从左到右读取复合索引中的列。如果在读取查询中的所有列之前查询中不存在该列,则不会使用索引。

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

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

What you have is a composite index. The order is important when your WHERE clause is not using all columns in the composite index.

Consider this query:

SELECT val1
FROM IndexTables
WHERE val1 = 'MyValue'

In order to know what index might be considered read from left to right the columns in your composite indexes. If the column doesn't exist in your query before you read all the columns in your query then the index won't be used.

IDX_IndexTables_1 (val1, val2): Reading from left to right val1 exists and it is our only column so this index would be considered

IDX_IndexTables_2 (val2, val1): Reading from left to right val2 doesn't exist in this query so it won't be used.

安穩 2024-08-14 14:11:26

前面的答案描述了如何使用每个索引的第一列。 (在 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

这表明,根据您的表收到的查询,可能会出现以下情况:拥有这两个索引的正当理由。

The previous answers describe how to use the first column of each index. (in the where clause).

I think it's also important to point out that the second column is useful because it potentially increases performance of queries that involve the second column.

The following query will be completed with JUST an index seek on IDX_1, saving valuable lookups to the base table (since val2 is already part of the index).

SELECT val2 from IndexTables where val1 = @someVal1

Likewise, the reversed index will optimize this query:

SELECT val1 from IndexTables where val2 = @someVal2

However, only one (it doesn't matter which) of the two indexes is need to optimize the following query:

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

This shows that, depending on the queries your table receives, there may be a legitimate reason to have both indexes.

酒解孤独 2024-08-14 14:11:26

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

不过,我会添加一些其他想法...

  • (col1, col2) 索引意味着您不需要单独在 col1 上建立索引
  • (col2, col1) 索引意味着您不需要单独在 col2 上建立索引
  • 顺序很重要如果这是覆盖(例如在 col1 上的 WHERE,SELECT col2),
  • 则方向(ASC/DESC)也很重要(其他问题 1其他问题 2)

Other folk have answered that they are different, and I agree.

I'll add some other thoughts though...

  • the (col1, col2) index means you don't need an index on col1 alone
  • the (col2, col1) index means you don't need an index on col2 alone
  • the order matters if this is covering (eg WHERE on col1, SELECT col2)
  • the direction (ASC/DESC) also matters (Other question 1, Other question 2)
公布 2024-08-14 14:11:25

是的。有一个区别。

复合索引 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

考虑复合索引的方法就像考虑纸质电话簿;它按姓氏列进行索引,然后按名字列进行索引:您可以按姓氏进行查找,但不能按名字本身进行查找。

Yes. There is a difference.

The composite index IDX_IndexTables_1 can be used for any query where the val1 column is used in the where clause.

The composite index IDX_IndexTables_2 can be used for any query where the val2 column is used in the where clause.

So, for instance IDX_IndexTables_2 cannot be used for this query (but IDX_IndexTables_1 can be used):

SELECT val1, val2 FROM IndexTables
WHERE val1 = some_value

but can be used for this query:

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

The way to think about a composite index is think about a paper telephone directory; It is indexed by the surname column, and then the firstname column: you can look up by surname but not by firstname on its own.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文