表的主键是否应该是该表的另一个索引中的列?

时间:2013-06-21 17:00:30

标签: sql sql-server tsql indexing ddl

假设我有一张这样的桌子。 Id是主键,所以我知道我得到了一个索引。

CREATE TABLE Employer
(
    Id VARCHAR(64) NOT NULL,
    EntityId VARCHAR(64) NOT NULL,
    Name VARCHAR(64) NOT NULL,
    Address1 VARCHAR(64) NOT NULL,
    Address2 VARCHAR(64) NOT NULL,
    City VARCHAR(64) NOT NULL,
    JobTitle VARCHAR(64) NOT NULL,
    StateCode VARCHAR(64) NOT NULL,
    ZipCode VARCHAR(64) NOT NULL,
    CONSTRAINT PK_Employer_Id PRIMARY KEY CLUSTERED (Id ASC)
    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)

假设我添加了另一个索引以帮助进行一些特殊搜索(尽管其原因并不相关)。是否有理由将Id(主键)作为索引中的一列包含在内?我有SQL专家告诉我这是浪费空间,因为索引已经以某种方式包含主键。

CREATE INDEX [idxEmployerByNameAddress1City] on [Employer] ([EntityId], [Id], [Name], [Address1], [City])

2 个答案:

答案 0 :(得分:0)

如果您的辅助索引不是以主键列开头,那么主键与辅助索引无关。

另一方面,如果您的索引基于前两列是唯一的,因为看起来可能就是这里的情况,那么在密钥中有更多列是没有意义的 - 这只会浪费索引中的空间

答案 1 :(得分:0)

索引用于各种目的。其中之一是满足仅使用索引中的列的查询。所以,如果您有类似的查询:

select col, max(pk)
from t
group by col

您在t(col)上有索引,然后查询必须从数据页中获取pk的值。如果主键位于索引中,则不需要原始数据页。

因此,在某些情况下,在索引中包含主键是个好主意。

顺便说一下,我完全赞同主键不应该是varchar(64)的注释。我建议您使用identity()使用整数主键。并且,出于某种原因,我认为拥有可变长度的主键是一个坏主意 - 可能是因为'A'' A'之间的混淆 - 这些是不同的,但可能是打印出来时看起来不一样。

我会进一步指出,如果主键存储在其他表中,那么索引中浪费空间的问题就没有用了。你浪费了太多的空间来存储如此大的主键,在索引中浪费更多的东西并不是一个主要问题。