【问题标题】:Execution plan oddity after re-enabling foreign key constraint重新启用外键约束后执行计划异常
【发布时间】:2009-07-04 17:56:04
【问题描述】:

我有一个奇怪的问题,在将 nocheck 设置为外部约束并重新启用它之后,

我得到了与nocheck 相同的过时执行计划。

为什么即使在使用以下语句再次添加检查后,SQL Server 仍会生成一个执行计划,就好像外部约束 FKBtoA 被禁用一样?

alter table B check constraint FKBtoA

[更新1]
到目前为止,放弃外国约束并阅读它是有效的。

alter table B drop constraint FKBtoA
alter table B add constraint FKBtoA foreign key (AID) references A(ID)

但是对于非常大的桌子,这似乎有点过头了 - 有没有更好的方法?

[回答]

我必须在 alter 语句中添加 WITH CHECK 以获取旧的执行计划

alter table B WITH CHECK add constraint FKBtoA foreign key (AID) references A(ID)

这是一个完整的 SQL 语句

create table A ( ID int identity primary key )
create table B ( 
    ID int identity primary key,
    AID int not null constraint FKBtoA references A (ID)
)

select  *
from    B
where   exists (select 1 from A where A.ID = B.AID)

alter table B nocheck constraint FKBtoA
GO
select  *
from    B
where   exists (select 1 from A where A.ID = B.AID)

alter table B check constraint FKBtoA
GO
select  *
from    B
where   exists (select 1 from A where A.ID = B.AID)

这是每个SELECT 语句的执行计划截图

禁用外键约束之前

禁用外键约束后

重新启用外键约束后

【问题讨论】:

    标签: sql sql-server tsql sql-execution-plan


    【解决方案1】:

    您的约束很可能已启用但不受信任,因此您的子表中可能存在孤立行。阅读 Hugo Kornelis 的这篇精彩文章:Can you trust your constraints?

    【讨论】:

    • 啊,哈!我需要在“alter table B 添加约束”中添加“with check”子句,所以它必须是“alter table B WITH CHECK add constraint ...”!当我用 NOCHECK 更改约束时,“sys.check_constraints.is_not_trusted”被设置为 1...
    • +1 表示“这个答案很有帮助”。我不知道任何诸如不受信任的约束之类的事情。
    • 这是一篇关于该主题的好文章 - explainextended.com/2009/10/15/…
    【解决方案2】:

    从您发布的脚本和计划中连接器的宽度来看,这些表中似乎没有任何数据。分析空表上的查询计划在很大程度上是无关紧要的:在单页读取时,优化器几乎肯定会选择全扫描。

    我假设您这样做是为了进行某种实验,在现实世界中您应该加入那些不使用内部 EXIST 的表。

    【讨论】:

    • 在我的情况下,无论表是否有任何数据,执行计划都保持不变......
    • Remus,如果 FK 约束是可信的,优化器将消除对父表的查找,因为总是有父行。
    • 对,我的回答并没有真正解决 OP 问题,而 Alex 的回答却一针见血。我的一般观点仍然是,空表上的计划通常与填充表上使用的实际计划完全不同。或者换句话说,这是一个没有人问过的不同问题的好答案;)
    • @Remus:这是我必须更新的一些现有的 更大 存储过程的实验,我发布的 SQL 代码只是实际发生的一小部分示例。如果表中的数据确实改变了执行计划,让我来玩一玩。感谢您让我以不同的方式解决我的问题。谢谢。
    【解决方案3】:

    我个人不知道,但我知道如何重建统计数据...

    【讨论】:

      猜你喜欢
      • 2017-11-10
      • 2012-03-07
      • 2012-05-08
      • 1970-01-01
      • 1970-01-01
      • 2011-05-14
      • 2015-09-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多