3

假设我在(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

聚类关键列被包含在每个非聚集索引的**叶级**处,这意味着数据在那里,一旦找到非聚集索引值 - 但它不在索引树中,所以它不能用于搜索/过滤。并且SQL Server足够聪明,可以避免再次添加已经是索引叶级别一部分的列 - 因此,在您的情况下,添加集群键列是毫无意义和多余的。 –

+0

是的,但是使用包含的列定义索引确保即使它从聚簇键中消失,它仍然保留在索引中,对吗? – Triynko

回答

1

对于一个非聚集索引,索引键/键出现在默认情况下,根和叶级..

此默认情况下,通过您的非聚集索引的定义不同..

当你创建一个非唯一聚簇索引,SQL Server将在根目录添加聚簇关键字以使其唯一,并且它也将以叶级别存在。

当您创建唯一聚簇索引时,SQL Server将不包含聚簇关键字在根级,但将包括在叶级..

所以来你的问题..

第一个问题,我需要明确包括用户名作为包含列,也将凭借聚集键,包括它的是有含蓄?

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

什么我知道在真正感兴趣的是,如果我不明确包括用户ID为包括会发生什么柱。它是否会被冗余地包含在索引中,一次作为集群密钥的一部分,再次作为包含列?还是SQL Server能够识别这个意图,并避免将它存储两次,因为它已经通过集群密钥包含在内了?

SQL Server是足够聪明,忽略这个..

第二个问题是,如果它不包括多余的,那么有没有到包括它明确地受益。

即使你添加SQL Server将忽略列

例如,将它确保用户名包含在未来,即使以这样的方式聚集键的变化,这不包括用户名和索引是否重建?

你不能改变聚集键定义,您必须删除并重新创建它,所以聚集键发生变化时,非聚集索引重建作为按照其定义,因此用户ID将出席