【问题标题】:Why put Clustered Indexes on Identity fields?为什么要在身份字段上放置聚集索引?
【发布时间】:2021-06-01 14:01:38
【问题描述】:

我刚刚回到 SQL Server,我正在构建一些表,我正在阅读的所有“指南”都表明应该将聚集索引放在身份字段上,因为它们“在不断增加”。我很难理解这一点。假设我有以下数据:

ID    Name              Date Promoted
1     John Jones        1/1/2019
2     Bill Franklin     1/15/2018
3     Tom Stewart       5/12/2020
4     Jeff Thomas       7/15/2017

我的大部分查询都可能基于推广日期。但是,我将有一个包含每个人的个人标识的表,因此将根据 ID 连接到另一个表。

在这种情况下,ID 是拥有聚集索引的最佳字段吗?如果是这样,有人可以用最简单的方式解释为什么吗?假设这个表有 500,000 条记录(我真的在简化我的示例数据问题),将聚集索引放在提升日期是否有意义,或者你会将聚集在 ID 和非聚集在提升日期?

【问题讨论】:

  • 对于 ymmv 的警告,它是一个好主意的原因有很多,但并非完全如此。如果您要连接两个表,则连接列上的聚集索引将允许有效的范围扫描/搜索以连接行。您可以非常轻松地测试在 Id 列上具有聚集索引并检查执行计划操作/统计 IO 的性能/IO 开销。
  • 是什么促使将索引放在Date Promoted 上的可能性?您会通过该列进行大量查找或连接吗?同样,ID 将如何使用?通常,您会将标识用于外键约束,从而进行连接;你也会这样吗?对如何使用这些数据一无所知,我假设您通常会通过ID 进行查询,很少通过Date Promoted 进行查询,但这显然取决于您的用例。 Radek 的回答涵盖了推理,但这些是您在评估索引时要牢记的问题。
  • 例如,如果这是一个 CRM,这是一个 Employees 表,您几乎肯定希望 ID 不仅是聚集索引,而且是主键。但如果这是例如用于填充促销日历的视图或非规范化表,那么将Promotion Date 设置为聚集索引可能是有意义的,尤其是如果您希望Promotion Date 是唯一的。 (如果您不这样做,您可能希望希望在聚集索引中包含 ID。)
  • 您的问题 - 以及您的所有研究 - 应该集中在“如何为您的特定架构和使用选择最合适的聚集索引”上。没有什么是免费的——大多数“建议”都集中在插入有效的“随机”数据(插入的值没有特定的模式)。对于员工表(或类似表),我根本无法想象该表上有多少 DML 活动,因此,它不适合讨论集群。
  • @SMor - 这是一个过于简单的例子。实际上,这些表将有几十个字段。我的观点是,如果我主要关心“日期 1 和日期 2 之间发生了什么”而不关心“ID 1 和 ID 2 之间发生了什么”,那么日期字段上的索引是一个更好的选择。可悲的是,我忘记的比大多数人知道的要多得多,而且我不记得日期字段上的索引是否有意义。

标签: sql-server indexing


【解决方案1】:

首先,请注意聚集索引定义了数据在磁盘上的存储顺序。如果您在 Date Promoted 列上有聚集索引,那么对于您的示例数据,插入第四条记录将需要移动磁盘上的所有三个先前记录。 (我正在简化这一点。)因此,该插入将比在 ID 列上使用聚集索引的插入要慢,后者只会在磁盘上附加一条新记录。这就是为什么最好使用“始终增加”列的原因。

此外,所有非聚集索引都包含聚集索引的值。因此,在可能的情况下,根据消耗的空间,最好在“最小”列上设置聚集索引。否则,将来随着表的增长,可能会导致空间问题。

最后,标识列通常用于连接表,因此也受益于索引以提高读取性能。如果您的聚集索引在您的身份列上,则已涵盖。否则,您可能需要一个单独的标识列索引来优化ID 的查找。

【讨论】:

  • 还应该注意,虽然不是严格要求,但出于性能原因,聚簇索引也应该是唯一的。如果我记得,如果聚集索引不是唯一的(source),SQL Server 将隐式添加唯一列。据推测,Date Promoted 列不会是唯一的,所以这是一个额外的问题。
猜你喜欢
  • 2011-06-11
  • 1970-01-01
  • 2012-05-20
  • 1970-01-01
  • 2010-11-18
相关资源
最近更新 更多