我有一个DELETE
针对具有全文索引列的表运行的语句,少数cascade
启用的外键。它看起来像这样:
DELETE FROM dbo.STUDENTS WHERE STUDENTID=@STUDENTID
有时会编译一个计划,其中包括对所有索引操作的非常高的行估计,这样会DELETE
花费很长时间并导致锁定。
我试图在 QueryStore 中强制执行一个好的计划,但这实际上不起作用,显示last forced plan failure description
.NO_PLAN
我已确保没有可能使计划无效的架构更改。
查看执行计划,我看到这DELETE
涉及到一个包含 FT 索引的系统表的连接:
加入 FT 索引是否意味着不支持计划强制?
在查看计划强制限制时,要点之一是:
但是,此限制并不意味着删除会导致计划强制失败。
考虑这 4 个查询,两个
SELECT
语句和两个DELETE
语句,该表在列上具有全文索引val
:唯一失败的查询是第二个查询,它使用以下
CONTAINS
语句:以失败的原因为
DQ_NO_FORCING_SUPPORTED
。两个删除语句的计划也显示了相同的
clustered index merge
运算符被强制执行:此来源提供了更多信息
DQ_NO_FORCING_SUPPORTED
:回答问题
我的回答是,这不是你应该看到的原因,
DQ_NO_FORCING_SUPPORTED
而不是NO_PLAN
错误。原因可能是由于另一个限制导致计划无效,索引更改,添加外键,......额外测试
添加表并使用 on delete 级联创建外键时,该外键引用上述查询中使用的表。我们预计删除会失败,因为我们不能再使用强制计划。
正如所料,我们得到
NO_PLAN
了两个删除语句重新实施计划给了我们救赎:
并消除了
NO_PLAN
问题对于具有全文索引的表也是如此,该表具有引用运行删除查询的主表的外键(带有 on delete 级联)。
关于高/低估计
如果删除没有执行那么多,添加
OPTION(RECOMPILE)
可能有助于高行估计,因为优化器在运行时“看到”变量,这可以为您提供更好的估计。使用查询计划发布不同的问题可能会带来不同的解决方法/解决方案。