我的SQL Server表仅由3列组成,它们具有唯一的索引。是否应该对索引进行聚类?

我的SQL Server表仅由3列组成,它们具有唯一的索引。是否应该对索引进行聚类?,sql,sql-server,indexing,Sql,Sql Server,Indexing,我有下表——非常简洁,每一列都是其他地方描述的实体的外键 这三列是唯一的索引,而不是主键,因为LocationId列需要容纳NULL。我本来打算在表中放入一个标识列作为主键,但后来我意识到索引结构本身保存所有数据,除了插入将填充索引的表行之外,没有任何理由再引用表中的任何内容 在这种情况下,我假设创建此索引的最有效方法是非聚集。如果我将其创建为集群,那么将努力将表中的数据排序为与索引相同的顺序,但这将是徒劳的,因为表中没有不在索引中的内容。(SQL Server会为此构建一个表吗?似乎有点浪费

我有下表——非常简洁,每一列都是其他地方描述的实体的外键

这三列是唯一的索引,而不是主键,因为LocationId列需要容纳NULL。我本来打算在表中放入一个标识列作为主键,但后来我意识到索引结构本身保存所有数据,除了插入将填充索引的表行之外,没有任何理由再引用表中的任何内容

在这种情况下,我假设创建此索引的最有效方法是非聚集。如果我将其创建为集群,那么将努力将表中的数据排序为与索引相同的顺序,但这将是徒劳的,因为表中没有不在索引中的内容。(SQL Server会为此构建一个表吗?似乎有点浪费。)

对此表最频繁的读取访问将是读取特定租户的所有行,按UnitId、LocationId排序


请建议-此索引是群集索引还是非群集索引?

如果您决定不使用主键,则需要群集索引

您是正确的,SQL实际存储一个单独的数据副本以支持聚集索引是一种浪费。但事实并非如此

您的数据将按排序顺序存储,因此您将能够根据一个用例高效地找到它

“每个表只能有一个聚集索引,因为数据行本身只能按一个顺序存储。表中数据行按排序顺序存储的唯一时间是当表包含聚集索引时。”-Source


但是…您声明“对该表最频繁的读取访问将是读取特定租户ID的所有行,按UnitId、LocationId排序。”如果您预计该表将变大,并且您根据除此之外的其他查找从该表中读取(甚至不频繁),然后,您可能希望考虑主键和一个或多个非聚集索引。如果此表变得非常大,即使是不频繁的读取也会非常痛苦。

如果您决定不使用主键,则需要使用聚集索引

您是正确的,SQL实际存储一个单独的数据副本以支持聚集索引是一种浪费。但事实并非如此

您的数据将按排序顺序存储,因此您将能够根据一个用例高效地找到它

“每个表只能有一个聚集索引,因为数据行本身只能按一个顺序存储。表中数据行按排序顺序存储的唯一时间是当表包含聚集索引时。”-Source


但是…您声明“对该表最频繁的读取访问将是读取特定租户ID的所有行,按UnitId、LocationId排序。”如果您预计该表将变大,并且您根据除此之外的其他查找从该表中读取(甚至不频繁),然后,您可能希望考虑主键和一个或多个非聚集索引。如果此表变得非常大,即使是不频繁的读取也可能会非常痛苦。

即使在这种情况下,我也喜欢使用合成键:我认为这样可以简化表的管理(例如,数字键显示插入顺序)。但我尊重那些不同意的人

你没有采取那种方法。您可能希望在每列上有三个单独的索引:

  • TenantId
  • UnitId
  • LocationId
实际上,您没有解释数据库是什么,但是如果“单位”和“位置”真的是两个不同的东西,我会感到惊讶。在我看来,“单位”有一个“位置”,你应该通过单位查找位置。但这只是基于命名的猜测

聚集索引的真正问题是:

  • 是否希望列成为表的主键
  • 是否需要单独的唯一索引
这两者之间几乎没有区别,只是一个唯一的索引将复制头的部分数据。当表上没有聚集索引时,我不确定这是否是额外的开销。也就是说,任何一种方法都可以替换上述索引之一——以索引中的第一个键为准

集群的主要问题是插入和删除记录时的碎片。但是,对于唯一索引上的索引碎片,您有一个非常相似的关注点。实际上,我不知道聚集索引碎片在某种意义上是否比唯一索引碎片“更糟糕”。然而,由于没有附加列,我怀疑它们是相似的


因此,我怀疑在您的数据模型中,您会希望将列定义为主键,SQL Server默认情况下将使用主键进行集群。

我非常喜欢使用合成键,即使在这种情况下:我认为这样可以更简单地管理表(例如,数字键显示插入顺序)。但我尊重那些不同意的人

你没有采取那种方法。您可能希望在每列上有三个单独的索引:

  • TenantId
  • UnitId
  • LocationId
实际上,您没有解释数据库是什么,但是如果“单位”和“位置”真的是两个不同的东西,我会感到惊讶。在我看来,“单位”有一个“位置”,你应该通过单位查找位置。但这只是基于命名的猜测

聚集索引的真正问题是:

  • 是否希望列成为表的主键
  • 是否需要单独的唯一索引
没有什么好消息