QueryStore 计划强制限制

Pet*_*ter 6 sql-server full-text-search execution-plan sql-server-2016 query-store

我有一个DELETE针对带有全文索引列的表运行的语句,cascade启用了一些外键。它看起来像这样:

DELETE FROM dbo.STUDENTS WHERE STUDENTID=@STUDENTID
Run Code Online (Sandbox Code Playgroud)

有时会编译一个计划,其中包括对所有索引操作的非常高的行估计,因此DELETE需要很长时间并导致锁定。

我试图迫使QueryStore一个很好的计划,但是这并不实际工作,表现出last forced plan failure descriptionNO_PLAN

我已确保没有可能使计划无效的架构更改。

查看执行计划,我看到这DELETE涉及到一个包含 FT 索引的系统表的连接:

在此处输入图片说明

加入 FT 索引是否意味着不支持计划强制?

Ran*_*gen 5

在查看计划强制限制时,要点之一是:

分布式查询或全文操作

但是,此限制并不意味着删除应该使计划强制失败。

考虑这 4 个查询、两个SELECT语句和DELETE一个表上的两个语句,列上有全文索引val

SELECT * 
FROM  dbo.fulltextindexed;

SELECT val 
FROM  dbo.fulltextindexed
WHERE CONTAINS(val, N'WOW');

DELETE top(1)  
FROM dbo.fulltextindexed;

DELETE top(1)  
FROM dbo.fulltextindexed
WHERE id <500 and id > -1;
Run Code Online (Sandbox Code Playgroud)

唯一失败的查询是第二个,它使用以下CONTAINS语句:

在此处输入图片说明

失败的原因是DQ_NO_FORCING_SUPPORTED.

两个 delete 语句的计划,也显示了相同的clustered index merge操作符被强制执行:

在此处输入图片说明

此来源提供了有关DQ_NO_FORCING_SUPPORTED以下方面的更多信息:

无法执行查询,因为计划与使用分布式查询或全文操作冲突

回答问题

加入 FT 索引是否意味着不支持计划强制?

我的回答是这不是原因,因为您应该看到错误DQ_NO_FORCING_SUPPORTED而不是NO_PLAN错误。原因可能是由于另一个限制导致计划无效、索引更改、添加外键等。


额外测试

添加表并使用删除级联创建引用上述查询中使用的表的外键时。我们预计删除会失败,因为我们不能再使用强制计划。

CREATE TABLE dbo.fulltexreference(id int identity(1,1) primary key not null, t1id int, val varchar(max));
ALTER TABLE dbo.fulltexreference add constraint FK_test foreign key(t1id) REFERENCES dbo.fulltextindexed(id) ON DELETE CASCADE;
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,我们得到NO_PLAN了两个删除语句 在此处输入图片说明

重新执行计划给了我们救赎:

在此处输入图片说明

并删除NO_PLAN问题

在此处输入图片说明

对于具有全文索引的表也是如此,该索引具有引用运行删除查询的主表的外键(带有删除级联)。

关于高/低估计

如果删除没有执行那么多,添加OPTION(RECOMPILE)可能有助于高行估计,因为由于优化器在运行时“看到”变量,这可以为您提供更好的估计。

使用查询计划发布不同的问题可能会带来不同的解决方法/解决方案。