是否需要在SQL Server中的多字段主键上创建索引?

时间:2017-01-05 12:28:04

标签: sql-server indexing primary-key

给出数据库表:

UserID (PK)
SomeTypeID (PK)
SomeSubTypeID (PK)
Data

您希望查询:

SELECT Data FROM Table WHERE UserID = {0} AND SomeTypeID = {1} AND SomeSubTypeID = {2}

您是否需要创建索引UserID, SomeTypeID, SomeSubTypeID或者它们是否构成主键意味着不需要这样做?

2 个答案:

答案 0 :(得分:3)

如果您将主键创建为:

CREATE TABLE TBL (UserID, SomeTypeID, SomeSubType, Data 
    CONSTRAINT PK PRIMARY KEY (UserID, SomeTypeID, SomeSubType))

然后,正在创建的默认索引是CLUSTERED索引。

通常所以不是所有时间),在查找数据时,您希望查询使用NON-CLUSTERED索引来过滤行,其中用于过滤行的列将构成索引的键以及从这些行作为INCLUDED列返回的信息(列),在本例中为DATA,如下所示:

CREATE NONCLUSTERED INDEX ncl_indx 
ON TBL (UserID, SomeTypeID, SomeSubType) INCLUDE (Data);

通过执行此操作,您无法通过CLUSTERED索引访问表数据。

但是,您可以指定希望PRIMARY KEY成为的索引类型,所以:

CREATE TABLE TBL (UserID, SomeTypeID, SomeSubType, Data 
    CONSTRAINT PK PRIMARY KEY NONCLUSTERED (UserID, SomeTypeID, SomeSubType));

Buuut ,因为您希望将其定义为PRIMARY KEY,然后您无法使用INCLUDE功能,因此您无法避免磁盘查找,以便从DATA列获取信息,这是您基本上使用默认CLUSTERED索引的位置。

Buuuuuut ,还有一种方法可以确保主键为您提供的唯一性并从INCLUDE功能中受益,从而减少磁盘数量/ O' S

您可以将NONCLUSTERED INDEX指定为UNIQUE,这将确保构成索引键的所有3列都是唯一的。

CREATE UNIQUE NONCLUSTERED INDEX ncl_indx 
ON TBL (UserID, SomeTypeID, SomeSubType) INCLUDE (Data);

通过执行所有这些操作,您的表格将成为HEAPwhich is not a very good thing。如果您在设计表格时考虑过它,并确定CLUSTERED INDEX的最佳群集密钥是(UserID,SomeTypeID,SomeSubType),那么最好将所有内容保留为您目前有它。

否则,如果您决定使用其他群集密钥,则可以添加此唯一的非聚集索引,如果您按照自己的意愿查询该表。

答案 1 :(得分:1)

只要您在过滤时使用主键中使用的所有列,就不需要创建单独的索引。您的主键在您的示例中没问题。

如果您计划过滤其中一列而不是其他列,请考虑创建单独的索引。例如:SELECT Data FROM Table WHERE UserID = {0}