2010-08-02 134 views
7

你好SQL Server引擎专家;请与我们分享一下您的见解......SQL Server性能:非聚簇索引+ INCLUDE列与聚簇索引 - 等效吗?

据我所知,非聚集索引上的INCLUDE列允许将其他非关键数据与索引页面一起存储。

我很清楚聚簇索引对非聚簇索引的性能好处,这是因为引擎在检索时必须采取的步骤少一步才能到达磁盘上的数据。

但是,由于INCLUDE列存在于非聚集索引中,因此可以预期以下查询在场景1和2中具有基本相同的性能,因为可以从场景2中的索引页中检索所有列,而不是诉诸表格数据页面?

QUERY

SELECT A, B, C FROM TBL ORDER BY A 

方案1

CREATE CLUSTERED INDEX IX1 ON TBL (A, B, C); 

方案2

CREATED NONCLUSTERED INDEX IX1 ON TBL (A) INCLUDE (B, C); 
+0

实际查询计划在切换索引设置时会说什么? – 2010-08-02 01:40:11

+0

它将取决于查询该表的总体查询工作量。 – 2010-08-02 01:52:09

+0

有趣的是,在查询计划中首选非聚集索引,但使用查询提示的可能性,引擎根据数据量决定最佳查询计划的复杂性以及谁知道其他因素对我而言是一个谜。我真的很想找人说出来,并说INCLUDE专栏不是因为某些原因或者其他原因而被破解的...... – Tahbaza 2010-08-02 01:54:30

回答

3

对于这个例子你可能实际使用非聚集索引可以获得更好的性能。但是,这实际上取决于你没有提供的附加信息。这里有一些想法。

SQL Server将信息存储在8KB页面中;这包括数据和索引。如果您的表只包含列A,B和C,则数据将存储在大致相同数量的数据页面和非聚集索引页面中。但是,如果表中有更多列,那么数据将需要更多页面。索引页面的数量不会有任何不同。

因此,在一个表中列的数量多于查询需求的情况下,查询对于非聚集覆盖索引(包含所有列的索引)将会更好地工作。它将能够处理更少的页面以返回您想要的结果。

当然,性能差异可能不会被看到,直到你得到大量的行。

5

确实,覆盖包含列的非聚集索引可以起到与聚集索引完全相同的作用。成本在更新时间:更多包含列意味着在基表(聚集索引中)中包含的列值发生更改时,必须更新更多索引。此外,随着列数越来越多,数据规模越来越大:数据库变得越来越大,这可能会使维护操作复杂化。

最后,您必须在附加索引的覆盖值和更多包含列与更新成本和数据大小增加之间找到平衡点。