SQL Server中如何实现组合索引

Tom*_*bes 4 index sql-server btree

我了解单索引列在 SQL Server 中是如何工作的,以及它是如何使用平衡树实现的。YouTube上有很多关于这个主题的有趣视频。但是,如果索引基于多列,我不明白它是如何工作的。例如:

CREATE NONCLUSTERED INDEX idxItemsCatState
ON Items (Category,OfferState)
INCLUDE ([Id],[Ranking])
Run Code Online (Sandbox Code Playgroud)

以及它如何加速查询,例如

SELECT ID, Ranking FROM Items where Category = 1 AND OfferState < 3
Run Code Online (Sandbox Code Playgroud)

它仍然作为 B-Tree 实现?它如何评估值的组合?此类功能有何限制?

Geo*_*son 5

要将行存储在 b 树中并执行查找,所需要的只是对行进行排序的顺序。就像您可以排序一样(Category),您也可以对元组进行排序(Category, OfferState)。在后一种情况下,行首先按 排序Category,然后通过按 排序来打破任何联系OfferState

结果索引将使用相同的 b 树结构,但 b 树中每个条目的值将是一个(Category, OfferState)元组。

以及它如何加速查询,例如......

对于您的查询,SQL Server 可以通过以下方式执行查找:

  • 寻找匹配的第一行Category = 1。这可以使用您熟悉的相同 b 树搜索来完成,SQL Server 只需要使用Category每个(Category, OfferState)元组的一部分。
  • 开始读取行,并继续直到OfferState >= 3找到一行

这样,SQL Server 将能够直接查找所需行范围的开头,读取这些行,并在行范围的末尾停止。请注意,您可以通过查看查询计划中运算符的Seek Predicate属性来了解此查找的工作原理Index Seek

更一般地,当您匹配相等性(使用)时(a, b, c, d, ...),跨列的多列索引可以支持对列的任何前导子集(例如(a)或)(a, b, c)进行查找=

如果您正在寻找一个范围(例如,b < 3),SQL Server 就不能再在索引中较晚的任何列上进行搜索。在这种情况下,它必须在 的每个不同值内执行单独的查找b,这是不受支持的(除非在更具体的情况下您可能不需要担心:跨分区表的分区)。