Question

I have seen this a number of times, when I run some analysis in SQL Server DataBase Engine Tuning Advisor it suggest me to create indexes like:

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

Does it really matter to include primary key (clustered index) column to included columns list? I always think that it is included by default as link to original row. Am I wrong?

Update: I think it is also important to note that it proposes such index for query like: SELECT [PrimaryKeyColumn] FROM [dbo].[SomeTable] WHERE ...[Conditions]... and it really influences performance and execution plan. So as far as I understand index doesn't contain really 'clustered index', but just some link to row. Is it so?

Was it helpful?

Solution

You can create the index with or without the INCLUDE: SQL Server will ignore it if the PrimaryKeyCol is the clustered index. That is, it won't store the clustered index value twice

For completeness, I probably would in case I ever change the clustered index

Edit:

I've observed via size that SQL Server deals with this intelligently
This is not as scientific as 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

OTHER TIPS

I think Tuning advisor detect you query and found that you have PrimaryKeyColumn in you select cause and you have Column1, Column2 and Column3 in where cause.

Tuning advisor think that.... if you index include PrimaryKeyColumn in the index SQL don't need to wast overhead to look up to get PrimaryKeyColumn data in data page(table data page). SQL engine would be able to take PrimaryKeyColumn value from index directly for you query. it save time..

Note that: There are bad side of the index(include column). at http://msdn.microsoft.com/en-us/library/ms190806.aspx contains useful information that might help you make decision.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top