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

时间:2012-02-15 08:56:36

标签: 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])

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

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

2 个答案:

答案 0 :(得分:6)

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

为了完整性,我可能会更改聚集索引

编辑:

我通过 size 观察到SQL Server智能地处理了这个问题 这不像Kalen Delaney's 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

答案 1 :(得分:0)

我认为Tuning顾问会检测到你的查询,发现你选择了原因,你有PrimaryKeyColumn,并且你在原因中有Column1,Column2和Column3。

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

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