如果计划在可用性组中的主节点上强制执行,那么该计划是否应用于在辅助程序上运行的查询?
我在寻找的答案涵盖了强制计划的两种可能性:
我读过以下文章,说明QS强制计划不会结转,但在文档中找不到任何权威的东西,也找不到任何关于计划指南的东西。
强制执行的确凿证据将是次级执行计划中存在Use Plan或PlanGuideName和PlanGuideDB属性。
发布于 2019-08-30 00:29:35
上的查询
使用Query在主目录上强制执行一个计划,显然它会强制执行次要的计划。
我尝试在一个非prod服务器上运行一个查询,然后用sp_query_store_flush_db刷新查询存储(这是将数据同步到辅助服务器所必需的)。这里是左边的第二个(请注意关于“只读”的圆圈警告),右边的主键是:

现在,我将单击右边的“强制计划”,然后刷新这两个视图:

因此,“强制”至少在底层查询库表中结转。这是有意义的,因为OP中引用的文章指出,在故障转移之后,查询强制应该保持在适当的位置:
问:当数据库从主副本到次副本的故障转移时,QDS会保留强制计划信息吗?答:是的,QDS将强制计划信息存储在sys.query_store_plan表中,因此,如果发生故障转移,您将继续在新主服务器上看到相同的行为。
但是强迫行为真的发生了吗?现在,我将在两台服务器上运行相同的查询。在主目录中,如预期的一样,计划XML中有"UsePlan“属性:
<QueryPlan DegreeOfParallelism="1" MemoryGrant="11096" CachedPlanSize="288" CompileTime="82"
CompileCPU="78" CompileMemory="2104" UsePlan="true">在UI中:

在辅助服务器(请注意不同的服务器名称)上,计划是不强制的。下面是相同的计划XML片段:
<QueryPlan DegreeOfParallelism="1" MemoryGrant="11096" CachedPlanSize="288" CompileTime="32"
CompileCPU="28" CompileMemory="1656">
的查询
我使用以下代码创建了一个关于主表的计划指南(为了保护无辜者而更改了表名):
EXEC sp_create_plan_guide
@name = 'plan-guide-test',
@stmt = N'SELECT TOP (1000) *
FROM dbo.TableName t
WHERE
NOT EXISTS
(
SELECT NULL
FROM dbo.OtherTable o
WHERE t.Id = o.TableName
);',
@type = N'SQL',
@module_or_batch = NULL,
@hints = N'OPTION (MAXDOP 1)';当然,计划指南在主要方面是有效的,执行计划就证明了这一点:
<StmtSimple StatementCompId="1" StatementEstRows="1000" ... StatementType="SELECT"
PlanGuideDB="..._UAT" PlanGuideName="plan-guide-test" ...>
在这一点上,我确实证实了计划指南被复制到第二阶段。
在辅助程序上运行相同的查询时,执行计划将丢失计划指南强制执行的所有迹象:
<StmtSimple StatementCompId="1" StatementEstRows="1000" ... StatementType="SELECT"
QueryHash="0xECF8A24F126EE77A" QueryPlanHash="0x0E93CF7FEAC1B6EA"
RetrievedFromCache="true" SecurityPolicyApplied="false">
https://dba.stackexchange.com/questions/246591
复制相似问题