外键可以损害查询性能

时间:2009-11-16 21:10:08

标签: sql-server-2005

正如我从this post所理解的,在某些情况下,外键可以提高查询性能。

我听到了相反的说法,即由于参照完整性检查,外键实际上可能会损害查询性能。在哪种情况下(如果有的话)是真的吗?


1)术语查询似乎具有误导性。我对各种表现处罚感兴趣。

2)是否有人对INSERT,DELETE或UPDATE语句的负面影响有任何实际数据(我知道这取决于特定的系统,但是,任何类型的真实世界测量都会受到赞赏)?

11 个答案:

答案 0 :(得分:19)

如果引用完整性需要外键,那么外键的存在应构成性能的基线

如果你不把座位放进去,你也可以问一下如果一辆车可以走得更快 - 一辆形状良好的汽车包括座位,就像一个结构良好的数据库包括外键一样

答案 1 :(得分:16)

我假设对于INSERT查询,约束 - 包括外键约束 - 会稍微降低性能。数据库必须检查你告诉它插入的内容是你的约束允许它插入的内容。

对于SELECT查询,外键约束不应对性能进行任何更改。

由于INSERTS几乎总是非常快,除了边缘情况外,少量的额外时间不会引人注意。 (构建一个几千兆字节的数据库,您可能希望禁用约束,然后在以后重新启用,只要您确定数据是好的。)

答案 2 :(得分:5)

理论上,是的:数据写入需要验证约束。

在实践中,很少:除非另有测量和证明,否则您可以假设没有性能影响。绝大多数情况下,由于其他问题而出现性能问题:

  • 错误的架构设计(缺少索引,错误的聚簇索引选择)
  • 争用(阻塞),再次由于错误的架构设计(表扫描保证锁定冲突)
  • 错误的查询设计

在设计良好的架构和良好的查询上,约束的成本将开始显示在非常的高吞吐量。发生这种情况时,有预防措施。

我的2c:从不牺牲一些难以捉摸的性能目标的正确性限制。在非常罕见的情况下,当约束确实是问题时,有测量结果表明情况就是这样,并且俗话说:如果你不得不问它需要多少费用,你就买不起。如果你不得不问问约束是否有问题,你就不能删除它们(没有违法行为)。

答案 3 :(得分:4)

外键可能导致子表中的插入(或某些更新)或父表中的删除需要更长时间。这是一件好事,因为这意味着它确保数据完整性仍然存在。除非您不想拥有有用的数据,否则没有任何理由可以跳过使用foriegn键。除非您在同一个父表中有许多外键,或者您要在一个批处理中插入或删除许多记录,否则通常不会发现很多差异。此外,我注意到,用户在插入或删除时比在select中更容忍几秒钟。用户也不能容忍所有不可靠的数据,这是没有外键约束的情况。

您需要对它们编制索引以提高选择查询的效果。

答案 4 :(得分:4)

对于INSERT / UPDATE / DELETE,简短回答是“是”。数据库需要检查参照完整性是否完整,是否允许创建/修改。或者在DELETE的情况下,可能会有一些级联要做。

对于SELECTs,实际上恰恰相反。外键有一个秘密的额外好处,可以向您展示您最有可能进行复杂JOIN并且具有非常常用字段的位置。这使得索引工作变得更加容易,并且您几乎可以保证所有FK字段都应该被编入索引。这使SELECTs 更多更快。

答案 5 :(得分:3)

外键检查比大多数人想象的要花费更多时间。使用Oracle 11g进行的当前测试和带有两个外键的表显示,插入大约800.000行的时间在启用外键时需要60秒,但在没有外键的情况下只需20秒。 (当然,外键列已编入索引)

无论如何,我同意所有其他海报,完整性约束不是一种选择,而是保持数据一致的唯一方法。但是,对于导入,特别是对于空表,如果时间很关键,可以选择在导入时禁用外键。

答案 6 :(得分:2)

如果外键有这样的影响,那就是INSERTS。在创建/修改记录时,数据库会对外键进行引用检查,而不是SELECTed。

答案 7 :(得分:2)

在大多数情况下,外键不会影响查询性能,强烈建议使用外键。通过帮助规范化,您将消除冗余数据,如果您通过添加基础索引(对于相应的外键)进行跟进,您将获得良好的查询性能。

外键可以帮助查询优化器获得给定查询的最佳查询计划。

外键检查是您更新数据时的一个因素(这是一个单独的考虑因素 - 我假设您的问题是查询 - 除非您通过单词查询暗示两者)。

答案 8 :(得分:0)

我相信这篇文章指出,在FK字段上添加索引可以提高性能,而不仅仅是FK关系提高了性能。除非正在进行JOIN操作,否则表上FK的存在不应对SELECT查询产生任何影响,此时,FK字段上的FK关系和索引将提高性能。

答案 9 :(得分:0)

如果您实施引用完整性,INSERT和UPDATE影响FK字段,则会更慢。但是,通常没什么可担心的,特别是因为很多DB的读取率为80%/ 20%。这也是值得付出的代价。

在外键上创建索引通常是有益的,但显然它取决于您正在运行的SELECT语句。

通常,由于规范化,您需要外键(这可以避免重复数据和同步问题)。归一化到3度,然后在分析现实世界的表现后,你可以考虑去标准化。

答案 10 :(得分:0)

外键减慢了插入和更改,因为必须验证每个外键引用。外键可以不影响选择,也可以使其更快,具体取决于DBMS是否使用外键索引。

外键对删除有复杂的影响。如果你要删除引用外键的东西,它不会影响任何东西,但是如果你要删除的东西被另一行/表中的外键引用,那么它通常会引起问题。

外键可能会导致表创建和更改中性能下降。

当然,这一切都假定外键验证正在使用中。