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

4

给定数据库表:

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

如果您希望进行查询:

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

你需要创建索引UserID,SomeTypeID,SomeSubTypeID吗?还是因为它们形成了主键,所以不需要创建索引?

2
主键已经创建了一种索引。除非您想要查询其他列并将它们隔离,否则只使用主键应该是可以的。更多细节请参考:https://msdn.microsoft.com/zh-cn/library/ms189039.aspx(假设您使用的是 Microsoft SQL)。 - Danie Schoeman
可能是重复问题... https://dev59.com/fnRB5IYBdhLWcg3w77kn?rq=1 - SS_DBA
2个回答

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);

通过这样做,您可以避免通过聚集索引访问表数据。
但是,您可以指定想要将主键作为的索引类型,因此:
CREATE TABLE TBL (UserID, SomeTypeID, SomeSubType, Data 
    CONSTRAINT PK PRIMARY KEY NONCLUSTERED (UserID, SomeTypeID, SomeSubType));

但是,因为您希望将其定义为PRIMARY KEY,所以您无法使用INCLUDE功能,因此无法避免磁盘查找以获取DATA列中的信息,这基本上就是具有默认CLUSTERED索引的情况。

但是,仍然有一种方法可以确保主键提供的唯一性并从INCLUDE功能中受益,以便尽可能减少磁盘I / O次数。

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

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

通过这些操作,您的表将成为一个“堆”,这不是一件好事。如果您在设计表时认真思考,并决定最佳的聚集索引键是(UserID、SomeTypeID、SomeSubType),那么最好保持当前状态。
否则,如果您选择了不同的聚集键,则可以添加此唯一的非聚集索引,如果您将像您所说的那样查询该表。

1
只要在筛选时使用主键中使用的所有列,就不需要创建单独的索引。在您的示例中,您的主键是可以的。
如果计划对其中一列而非其他列进行过滤,请考虑创建单独的索引。例如:SELECT Data FROM Table WHERE UserID = {0}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接