为什么SQL Server Tuning Advisor建议将PRIMARY KEY添加到索引的包含列?

And*_*aev 4 sql-server indexing database-tuning

我已经看过很多次了,当我在SQL Server DataBase Engine Tuning Advisor中运行一些分析时,它建议我创建索引,如:

CREATE NONCLUSTERED INDEX [_index] ON [dbo].[SomeTable] 
(
    [Column1] ASC,
    [Column2] ASC,
    [Column3] ASC
)
INCLUDE ([PrimaryKeyColumn])
Run Code Online (Sandbox Code Playgroud)

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

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

gbn*_*gbn 6

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

为了完整起见,我可能会在以后更改聚簇索引

编辑:

我已经通过大小观察到SQL Server智能地处理这个问题.
这不像Kalen Delaney关于非聚集索引关键字那样科学

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
Run Code Online (Sandbox Code Playgroud)