在已包含集群密钥的非聚集索引中包含“包含”列会产生什么影响?

时间:2016-08-04 19:25:43

标签: sql-server indexing sql-server-2014 non-clustered-index clustering-key

假设我在(RetailerID, PurchaseDate, UserID)上集群表。这是“集群密钥”,集群密钥始终包含在所有非集群索引中。 https://stackoverflow.com/a/23057196/88409 https://stackoverflow.com/a/2747869/88409

接下来,我创建一个非聚集索引“StorePurchasesIndex”,键入(RetailerID, StoreID, PurchaseDate),以便更快地查找仅包含特定商店的子集。

第一个问题是,我是否需要明确地将UserID作为包含列包含在内,还是由于包含它的群集密钥而隐式存在?我很确定在这种情况下我不需要明确包含UserID,但如果我错了,请纠正我。

我真正感兴趣的是,如果我明确地将UserID包含为包含列,会发生什么。它是否会作为群集密钥的一部分冗余地包含在索引中,并再次作为包含列?或者SQL Server是否识别意图并避免将其存储两次,因为它已经通过群集密钥包含在内?

第二个问题是,如果它不包含多余,那么明确地包含它是否有好处。例如,它是否会确保将来包含UserID,即使群集密钥以排除UserID并重建索引的方式更改?

1 个答案:

答案 0 :(得分:1)

对于非聚簇索引,默认情况下索引键/键存在于根级别和叶级别。

此默认情况因非聚集索引的定义而异。

当您创建一个非唯一的聚簇索引时,SQL Server将在root用户添加聚簇键以使其唯一,并且它也将存在于叶级别中。

创建唯一的聚簇索引时,SQL Server不会在根级别包含聚簇密钥,但会包含在叶级别。

所以提出你的问题..

  

第一个问题是,我是否需要明确地将UserID作为包含列包含在内,还是由于包含它的聚类键而隐式存在?

是的,你是对的,你不需要在包含列表中添加用户ID ..

  

我真正感兴趣的是,如果我明确将UserID作为包含列包含在内,会发生什么。它是否会作为群集密钥的一部分冗余地包含在索引中,并再次作为包含列?或者SQL Server是否识别意图并避免将其存储两次,因为它已经通过群集密钥包含在内?

SQL Server非常聪明,可以忽略它。

  

第二个问题是,如果它没有包含多余,那么明确包含它是否有好处。

即使添加SQL Server也会忽略列

  

例如,即使群集密钥以排除UserID并重建索引的方式更改,它是否会确保将来包含UserID?

您无法更改群集密钥定义,您必须删除并重新创建它,因此当群集密钥更改时,非聚簇索引将根据其定义重建,因此将存在userid