4

我已经多次看到这种情况,当我在 SQL Server 数据库引擎优化顾问中运行一些分析时,它建议我创建如下索引:

CREATE NONCLUSTERED INDEX [_index] ON [dbo].[SomeTable] 
(
    [Column1] ASC,
    [Column2] ASC,
    [Column3] ASC
)
INCLUDE ([PrimaryKeyColumn])

将主键(聚集索引)列包含到包含的列列表中真的很重要吗?我一直认为它默认包含在原始行的链接中。我错了吗?

更新: 我认为同样重要的是要注意它提出了这样的查询索引,例如:SELECT [PrimaryKeyColumn] FROM [dbo].[SomeTable] WHERE ...[Conditions]... 它确实会影响性能和执行计划。据我所知,索引并不包含真正的“聚集索引”,而只是一些指向行的链接。是这样吗?

4

2 回答 2

6

您可以创建带有或不带有 INCLUDE 的索引:如果PrimaryKeyCol 是聚集索引,SQL Server 将忽略它。也就是说,它不会将聚集索引值存储两次

为了完整起见,我可能会在我更改聚集索引的情况下

编辑:

我通过size观察到SQL Server 可以智能地处理这个问题
这不像Kalen Delaney 的 More About Nonclustered Index Keys那样科学

DROP TABLE IncludeTest;
GO
CREATE TABLE IncludeTest (
    BadClusteredKey uniqueidentifier DEFAULT NEWID() PRIMARY KEY,
    OtherCol AS CHECKSUM(BadClusteredKey) % 10000,
    Filler char(200) NOT NULL DEFAULT 'a and lots of spaces'
    );
GO

INSERT IncludeTest (Filler) VALUES (DEFAULT);
GO
INSERT IncludeTest (Filler) SELECT Filler FROM IncludeTest
GO 20
SELECT COUNT(*) FROM IncludeTest;

EXEC sp_spaceused 'IncludeTest', 'true'
GO -- 400680 KB, 1920 KB

CREATE INDEX IX_OtherCol1 ON IncludeTest (OtherCol);
GO
EXEC sp_spaceused 'IncludeTest', 'true'
GO -- 400680 KB, 29024 KB KB

DROP INDEX IncludeTest.IX_OtherCol1
GO
EXEC sp_spaceused 'IncludeTest', 'true'
GO -- 400680 KB, 1920 KB

CREATE INDEX IX_OtherCol2 ON IncludeTest (OtherCol) INCLUDE (BadClusteredKey);
EXEC sp_spaceused 'IncludeTest', 'true'
GO -- 400680 KB, 29024 KB

DROP INDEX IncludeTest.IX_OtherCol2
GO
EXEC sp_spaceused 'IncludeTest', 'true'
GO -- 400680 KB, 1920 KB
于 2012-02-15T10:08:56.253 回答
0

我认为 Tuning advisor 检测到您的查询,发现您在选择原因中有 PrimaryKeyColumn,并且在 where 原因中有 Column1、Column2 和 Column3。

调优顾问认为....如果您在索引中包含 PrimaryKeyColumn,则 SQL 不需要浪费开销来查找数据页(表数据页)中的 PrimaryKeyColumn 数据。SQL 引擎将能够直接从索引中获取 PrimaryKeyColumn 值供您查询。它节省时间..

请注意:索引有不好的一面(包括列)。http://msdn.microsoft.com/en-us/library/ms190806.aspx包含有用的信息,可以帮助您做出决定。

于 2012-02-15T09:12:25.627 回答