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 description的NO_PLAN。
我已确保没有可能使计划无效的架构更改。
查看执行计划,我看到这DELETE涉及到一个包含 FT 索引的系统表的连接:
加入 FT 索引是否意味着不支持计划强制?
在查看计划强制限制时,要点之一是:
分布式查询或全文操作
但是,此限制并不意味着删除应该使计划强制失败。
考虑这 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问题
对于具有全文索引的表也是如此,该索引具有引用运行删除查询的主表的外键(带有删除级联)。
关于高/低估计
如果删除没有执行那么多,添加OPTION(RECOMPILE)可能有助于高行估计,因为由于优化器在运行时“看到”变量,这可以为您提供更好的估计。
使用查询计划发布不同的问题可能会带来不同的解决方法/解决方案。
| 归档时间: |
|
| 查看次数: |
291 次 |
| 最近记录: |