创建带有包含列的索引

非聚集索引可以通过包含索引键列以及非键列实现扩展。非键列存储在索引 B 树的叶级别。

包含非键列的索引在它们包含查询时可提供最大的好处。这意味着索引包含查询引用的所有列。有关详细信息,请参阅具有包含列的索引

磁盘空间要求

将非键列添加到索引中要使用更多的空间来存储索引。特别是,将 varchar(max)、nvarchar(max)、varbinary(max) 或 xml 数据类型添加为非键列会显著增加磁盘空间要求,因为列值被复制到索引的叶级别中,同时还保留在表或聚集索引中。

确定带有包含列的索引的磁盘空间要求的过程与非聚集索引一样。有关信息,请参阅确定索引的磁盘空间要求

性能注意事项

这样可以提高选择操作的性能,因为查询优化器可以在索引中找到需要的所有列数据,而不用访问表或聚集索引。但是,拥有太多的包含列会增加对基础表或索引视图执行插入、更新或删除等操作所需的时间,因为增加了索引维护的工作量。

示例

A. 包含一个查询

以下示例在带有四个包含列的 Person.Address 表上创建了一个非聚集索引。索引键列是 PostalCode,非键列是 AddressLine1, AddressLine2, City, 和 StateProvinceID。

USE AdventureWorks2008R2;
GO
CREATE NONCLUSTERED INDEX IX_Address_PostalCode
ON Person.Address (PostalCode)
INCLUDE (AddressLine1, AddressLine2, City, StateProvinceID);
GO

索引将涵盖此查询。

SELECT AddressLine1, AddressLine2, City, StateProvinceID, PostalCode
FROM Person.Address
WHERE PostalCode BETWEEN '98000' and '99999';
GO

B. 超过索引大小限制

在以下示例中,CREATE INDEX 语句的 INCLUDE 子句用于通常超过 900 字节最大键列大小限制的索引列。Production.ProductReview 表包含下列这些列:ProductID、(int)、ReviewerName、(nvarchar (50)) 和 Comments (nvarchar (3850))。查询中经常用到这些列,但 Comments 列太大,无法作为索引键列。但是,通过使用 INCLUDE 子句,可以将 Comments 列作为非键列添加到索引中。

USE AdventureWorks2008R2;
GO
CREATE NONCLUSTERED INDEX IX_ProductReview_ProductID_ReviewerName
ON Production.ProductReview (ProductID, ReviewerName)
INCLUDE (Comments);
GO

索引将涵盖此查询。

SELECT Comments
FROM Production.ProductReview 
WHERE ProductID = 937;
GO

创建带有包含列的索引