在一个外键上创建聚集索引经常会与另一个表连接。

3
我最近在对一张表进行性能优化/查询调优时,对使用外键作为聚集索引有疑问。表结构/关系如下:
我正在一个发票应用程序中工作,在发票和发票行项目上可以定义指南的最大允许金额。
有一个父表仅存储适用指南的条件,例如创建发票的州、邮政编码或行项目类型。GuidelineCondition。
有两个子表,仅定义能够提交的货币限制。GuidelineInvoiceAllowable、GuidelineLineItemAllowable。
这两个子表几乎完全通过与父条件表的连接来访问。这两个子表都有一个基于合成无意义键的聚集索引。我将聚集索引交换到了GuideLineCondition表的外键GuidelineConditionID上。父表的聚集索引是合成键/主键GuidelineConditionID。现在,由于连接中的两个表都具有相同连接列上的有序聚集索引,因此优化器可以高效地对这些表进行合并连接。
像这样将聚集索引设置为外键违反了一些选择聚集索引的最佳实践,但由于表的访问模式,这似乎是正确的决定。
请参见此帖子以获取我正在考虑的一些最佳实践。SQL Server-何时使用聚集索引与非聚集索引? 数据库专家能否评论我是否做出了正确的决定?

1
既然你要求评论 =),这是一个好问题,我理解你反对最佳实践的观点。如果符合以下条件,我也可以采用这种方法:那些子表是域表,几乎不会插入/删除;该连接频繁使用;已经使用实际生产备份(真实数据)模拟真实工作负载(酸性测试)测试了该解决方案。我建议探索另一种方法:使用索引视图。 - jean
数据很少插入,从不删除。连接经常访问,并将使用生产质量数据进行测试,而我们开发环境中的数据也不错。索引视图将是一个很好的解决方案,但实施它将超出解决原始问题的时间范围。 - Hunter Nelson
1个回答

2
那些是指导方针,而不是绝对规则。简短的答案是没有一种适合所有情况的方法。要确信您的聚集索引有效,您需要进行测试。是的 - 您的设置中存在父/详细关系,并且通常可以通过父项 (直接或间接地) 访问详细信息,这种情况通常适合在父表的 pk 上进行聚集。我将进一步建议详细表的 pk 应包括父表的 pk 值,这意味着它将由至少 2 个列组成。
再次强调 - 确定解决方案是否有效的唯一方法是尝试并进行测试。您已经做到了。

我现在有一个非聚集主键,它是详细表上的合成自动编号键,以及父表外键的聚集索引。您是说非聚集主键应该包括外键,还是外键上的聚集索引应该包括合成键? - Hunter Nelson
"合成自动编号" 我们可以使用SQL Server的术语吗?假设是一个标识列?暂时忽略聚集。是的 - 您的详细表的主键应包含父表的fk列。以AdventureWorks DB中的销售订单表为例。 - SMor
合成键是一个真实的术语,我说合成自动编号来表示它是一个自动编号的int而不是GUID,这可能会影响到是否可以将其作为外键聚集的答案。 - Hunter Nelson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接