在 MS SQL 服务器中创建索引时 INCLUDE() 函数做什么?

What INCLUDE() function does when creating index in MS SQL Server?

使用 INCLUDE 函数与不使用函数创建索引有什么区别?

下面两个索引有什么区别?

CREATE NONCLUSTERED INDEX SomeName ON SomeTable (
    ColumnA
    ,ColumnB
    ,ColumnC
    ,ColumnD
    ) INCLUDE (
    ColumnE
    ,ColumnF
    ,ColumnG
    )

对比

CREATE INDEX SomeName ON SomeTable (
    ColumnA
    ,ColumnB
    ,ColumnC
    ,ColumnD
    ,ColumnE
    ,ColumnF
    ,ColumnG
    )

当执行计划使用索引时,它可以访问索引中的所有列。如果给定 table 中的所有列都在索引中,则无需引用原始数据页。消除数据页查找可以提高效率。

但是,在索引中包含列会对索引结构本身产生开销(除了复制值之外)。

INCLUDE 关键字允许将列值放在索引中,而不会产生额外索引结构的开销。目的是解决查询,而不必在原始数据页上查找列信息。

INCLUDE 子句在 lowest/leaf 级别添加数据,而不是在索引树中。这使得索引更小,因为它不是树的一部分。

INCLUDE 列不是索引中的键列,因此它们没有排序。这意味着它对于谓词、排序等并不是真正有用。但是,如果您在键列的几行中进行剩余查找,它可能会很有用。

INCLUDE 列不是索引中的键列,因此它们没有排序。这使得它们通常不适用于 JOIN 或排序。而且因为它们不是键列,所以它们不像键列那样位于整个 B 树结构中

通过添加包含(或非键)列,您可以创建涵盖更多查询的非聚集索引。这是因为非键列具有以下优点:

  • 它们可以是不允许作为索引键列的数据类型。
  • 数据库引擎在计算索引键列数或索引键大小时不考虑它们。

当查询中的所有列都作为键列或非键列包含在索引中时,包含列的索引可以显着提高查询性能。实现性能提升是因为查询优化器可以在索引中找到所有列值; table 或聚簇索引数据未被访问,导致磁盘 I/O 操作减少。

有关详细信息,请参阅 Microsoft 文档:Create Indexes with Included Columns