【问题标题】:Creating a clustered index on a foreign key is frequently joined to another table在外键上创建聚集索引经常连接到另一个表
【发布时间】:2018-04-22 15:30:45
【问题描述】:

我最近正在对表进行一些性能优化/查询调整,并且有一个关于使用外键作为聚集索引的问题。表结构/关系如下:

我正在处理一个开票应用程序,并且可以在发票和发票的行项目上定义允许提交的最大金额的准则。

有一个父表仅存储应用准则的条件,例如创建发票的状态、邮编或行项目类型。 GuidelineCondition

有两个子表只定义了可以提交的货币限额。 GuidelineInvoiceAllowable, GuidelineLineItemAllowable

这两个子表几乎只能通过连接到父条件表来访问。两个子表在一个合成的无意义键上都有聚集索引。我将聚集索引交换为GuideLineCondition 表的外键GuidelineConditionID。父表的聚集索引是合成键/主键GuidelineConditionID 这允许优化器有效地对这些表进行合并联接,因为联接中的两个表现在都在同一个联接列上对聚集索引进行了排序。

像这样使聚集索引成为外键违反了选择聚集索引的一些最佳实践,但由于表的访问模式,它似乎是正确的调用。

请参阅这篇文章了解我正在考虑的一些最佳做法。 SQL Server - When to use Clustered vs non-Clustered Index?

数据库专家能否评论我是否做出了正确的决定?

【问题讨论】:

  • 既然您要求发表评论 =)。这是一个很好的问题,我明白你反对最佳实践的观点。只有在以下情况下,我也可以这样做:那些子表是域表,几乎从不插入/删除;那个连接被打疯了;已经使用模拟实际工作负载(酸性测试)的实际生产备份(真实数据)测试了该解决方案。我可以推荐探索的另一种方法:使用索引视图
  • 数据很少被插入并且从不被删除。该连接会定期访问,并将在几周内使用生产质量数据进行测试,我们开发环境中的数据也不错。索引视图将是一个很好的解决方案,但实施它会超出分配给解决原始问题的时间范围。

标签: sql-server performance tsql indexing sql-tuning


【解决方案1】:

这些是指南,不是绝对的。简短的回答是,没有一种万能的方法。要确定您的聚集索引是否有效,您需要进行测试。是的 - 像您这样的设置,您有父/详细信息关系并且通常通过父(直接或间接)访问详细信息,这种情况通常适合在父的 pk 上进行聚类。我将更进一步,建议明细表的 pk 应包括父表 pk 值——这意味着它将至少包含 2 列。

再说一次 - 了解您的解决方案是否有效的唯一方法是尝试并测试。你已经做到了。

【讨论】:

  • 我现在有一个非聚集主键,它是详细表上的合成自动编号键和父表外键上的聚集索引。你是说非聚簇主键应该包含外键,还是说外键上的聚簇索引应该包含合成键?
  • "synthetic auto-number" 可以只用sql server的术语吗?大概是一个身份列?让我们暂时忽略聚类。是的 - 您的详细信息表的主键应包含父级的 fk 列。以销售订单表的 Adventureworks 数据库为例。
  • stackoverflow.com/questions/13225928/… 合成键是实数,我说合成自动编号表示它是自动编号 int 而不是 GUID,这可能会影响是否可以接受的答案作为外键聚集在它上面..
猜你喜欢
  • 2012-01-31
  • 1970-01-01
  • 1970-01-01
  • 2015-01-21
  • 1970-01-01
  • 2011-01-26
  • 2017-08-20
  • 2020-01-01
  • 2012-12-21
相关资源
最近更新 更多