给出数据库表:
UserID (PK)
SomeTypeID (PK)
SomeSubTypeID (PK)
Data
您希望查询:
SELECT Data FROM Table WHERE UserID = {0} AND SomeTypeID = {1} AND SomeSubTypeID = {2}
您是否需要创建索引UserID, SomeTypeID, SomeSubTypeID
或者它们是否构成主键意味着不需要这样做?
答案 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);
通过执行所有这些操作,您的表格将成为HEAP
,which is not a very good thing。如果您在设计表格时考虑过它,并确定CLUSTERED INDEX
的最佳群集密钥是(UserID,SomeTypeID,SomeSubType),那么最好将所有内容保留为您目前有它。
否则,如果您决定使用其他群集密钥,则可以添加此唯一的非聚集索引,如果您按照自己的意愿查询该表。
答案 1 :(得分:1)
只要您在过滤时使用主键中使用的所有列,就不需要创建单独的索引。您的主键在您的示例中没问题。
如果您计划过滤其中一列而不是其他列,请考虑创建单独的索引。例如:SELECT Data FROM Table WHERE UserID = {0}