首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >查询优化器和FK约束

查询优化器和FK约束
EN

Stack Overflow用户
提问于 2010-12-15 05:53:09
回答 2查看 582关注 0票数 0

我读到,如果您使用WITH NOCHECK添加FK,查询优化器将不会在它生成的任何查询计划中使用此FK。这让我开始思考,在生成查询计划时,查询优化器如何以及为什么会考虑FK?如果有FK,查询引擎会有什么好处?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-12-15 08:01:57

如果外键是“受信任的”,则SQL Server可以利用该约束所针对的列位于另一个表的唯一索引中这一事实。如果您有一个与FK所针对的表的联接,并且您只使用键中存在的列,则它可以删除联接。

例如,假设您有两个表:OrderProduct,而Order表有一个ProductId,它是Product.Id的外键。然后,优化器知道这个查询:

代码语言:javascript
运行
复制
SELECT Order.Id, Product.Id
FROM Order
LEFT OUTER JOIN Product ON Product.Id = Order.ProductId

..。与以下查询相同:

代码语言:javascript
运行
复制
SELECT Order.Id, Order.ProductId
FROM Order

。。并且可以删除对Product的额外联接。它之所以能做到这一点,是因为它知道Order中的每一行在Product中最多只能有一行,而且这些值是相同的,因此删除连接不会影响查询。

如果Order.ProductId不是NULL,那么它将能够对内部连接执行相同的操作。如果它可以为空,它就不能,因为它不知道Product中会有一行,所以连接可能会导致Order行被删除;这是不同的。

但是,如果您将Product.Name添加到SELECT子句,那么在这两种情况下,它都不能删除联接。

是的,我知道:它看起来不是很有用。在实践中,我并没有真正看到太多的案例,这实际上是不同的。通常,它只是动态生成的SQL或代码生成的一个因素,在这些情况下,连接是固定的,只有SELECT子句改变。

你可以在这里读到这篇文章:

http://explainextended.com/2009/10/15/constraints-and-the-optimizer-in-sql-server-foreign-key/

至于为什么WITH NOCHECK会有不同,当指定时,键不是“受信任的”,这意味着可能不是列中的所有值都满足约束。WITH NOCHECK只对新数据强制执行该约束;任何旧数据都可能违反该假设,因此SQL Server采取安全措施,并将联接保留在那里。

票数 2
EN

Stack Overflow用户

发布于 2010-12-15 06:17:32

可能发生的情况是,如果您有一个连接其他外键表的查询,并且存在外键约束,则查询引擎可以利用外表索引。

您可以通过查看SQL Server Management Studio中的查询执行计划来对其进行测试。在[查询]->[包含实际执行计划]。尝试一个使用FK,另一个使用NOCHECK,看看区别。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4444646

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档