【问题标题】:What's the effect of including an "include" column in a non-clustered index that's already part of the clustering key?在已经是集群键的一部分的非聚集索引中包含“包含”列有什么影响?
【发布时间】:2016-12-11 01:48:52
【问题描述】:

假设我将一个表聚集在 (RetailerID, PurchaseDate, UserID) 上。这就是“聚集键”,聚集键总是包含在所有非聚集索引中。 https://stackoverflow.com/a/23057196/88409 https://stackoverflow.com/a/2747869/88409

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

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

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

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

【问题讨论】:

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

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


【解决方案1】:

对于非聚集索引,索引键/键默认存在于根和叶级别..

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

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

当你创建一个唯一的聚集索引时,SQL Server 不会在根级包含聚集键,但会在叶级包含......

所以来回答你的问题..

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

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

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

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

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

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

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

您不能更改聚集键定义,您必须删除并重新创建它,因此当聚集键更改时,非聚集索引会根据其定义重新构建,因此用户 ID 将存在

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-27
    • 2018-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-14
    相关资源
    最近更新 更多