Sql server 什么';包括一个“s”字的效果是什么;包括「;非聚集索引中';它已经是集群密钥的一部分了吗?

Sql server 什么';包括一个“s”字的效果是什么;包括「;非聚集索引中';它已经是集群密钥的一部分了吗?,sql-server,indexing,sql-server-2014,non-clustered-index,clustering-key,Sql Server,Indexing,Sql Server 2014,Non Clustered Index,Clustering Key,假设我在(RetailerID、PurchaseDate、UserID)上集群了一个表。这就是“聚类键”,聚类键总是包含在所有非聚类索引中。 接下来,我创建一个非聚集索引“StorePurchasesIndex”,键入(RetailerID、StoreID、PurchaseDate),以便更快地查找只包含特定商店子集的商店 第一个问题是,我是否需要显式地将UserID包含为包含的列,还是通过包含它的集群键隐式地包含在其中?我很确定,在这种情况下,我不需要显式地包含UserID,但如果我错了,请

假设我在(
RetailerID、PurchaseDate、UserID
)上集群了一个表。这就是“聚类键”,聚类键总是包含在所有非聚类索引中。

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

第一个问题是,我是否需要显式地将
UserID
包含为包含的列,还是通过包含它的集群键隐式地包含在其中?我很确定,在这种情况下,我不需要显式地包含
UserID
,但如果我错了,请纠正我

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


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

对于非集群索引,默认情况下,索引键在根和叶级别存在

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

创建非唯一聚集索引时,SQL Server将在根目录中添加聚集键以使其唯一,并且它也将出现在叶级别

创建唯一聚集索引时,SQL Server不会在根级别包含聚集键,而是在叶级别包含聚集键

所以来回答你的问题

第一个问题是,我是否需要显式地将UserID包含为包含的列,还是通过包含UserID的集群键隐式地包含UserID

是的,您是对的,您不需要在包含列表中添加userid

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

SQL Server足够聪明,可以忽略这一点

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

即使添加SQL Server,也会忽略该列

例如,即使集群键更改为排除UserID并重建索引,它是否会确保将来包含UserID


您不能更改聚集键定义,您必须删除并重新创建它,因此当聚集键更改时,非聚集索引将根据其定义重建,因此将显示userid

聚集键列包含在每个非聚集索引的叶级,这意味着数据就在那里,一旦找到非聚集索引值,但它不在索引树中,因此不能用于搜索/筛选。SQL Server足够聪明,可以避免再次添加已经是索引叶级别一部分的列-因此在您的情况下,添加群集键列是毫无意义和多余的是,但是使用包含的列定义索引可以确保即使它从群集键消失,它仍保留在索引中,对吗?