Pau*_*ite 16 sql-server execution-plan availability-groups query-store plan-guides
如果在可用性组中的主节点上强制执行计划,它是否应用于在辅助节点上运行的查询?
我正在寻找涵盖计划强制两种可能性的答案:
我已阅读以下内容,这些内容表明 QS 强制计划不会结转,但在文档中找不到任何权威信息,或任何有关计划指南的信息。
强制的决定性证据是辅助节点的执行计划中存在Use Plan
或PlanGuideName
和PlanGuideDB
属性。
Jos*_*ell 19
使用 Query Store 在主服务器上强制执行计划看起来肯定会在辅助服务器上强制执行计划。
我尝试在非生产服务器上运行查询,然后刷新查询存储sp_query_store_flush_db
(这是将数据同步到辅助服务器所必需的)。这是左边的次要(注意关于“只读”的带圆圈的警告),右边是主要的:
现在我将点击右侧的“Force Plan”,然后刷新两个视图:
所以“强制”至少在底层查询存储表中延续。这是有道理的,因为 OP 中引用的文章指出,在故障转移后查询强制应保持原位:
问:当数据库从主副本故障转移到辅助副本时,QDS 会保留 FORCED Plan 信息吗?
答:是的,QDS 将强制计划信息存储在 sys.query_store_plan 表中,因此在故障转移的情况下,您将继续在新主节点上看到相同的行为。
但这种强迫行为真的发生了吗?我现在将在两台服务器上运行相同的查询。在主服务器上,正如预期的那样,“UsePlan”属性位于计划 XML 中:
<QueryPlan DegreeOfParallelism="1" MemoryGrant="11096" CachedPlanSize="288" CompileTime="82"
CompileCPU="78" CompileMemory="2104" UsePlan="true">
Run Code Online (Sandbox Code Playgroud)
在用户界面中:
在辅助服务器上(注意不同的服务器名称),该计划没有被强制执行。这是相同的计划 XML 片段:
<QueryPlan DegreeOfParallelism="1" MemoryGrant="11096" CachedPlanSize="288" CompileTime="32"
CompileCPU="28" CompileMemory="1656">
Run Code Online (Sandbox Code Playgroud)
我使用此代码创建了主要的计划指南(表名已更改以保护无辜者):
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)';
Run Code Online (Sandbox Code Playgroud)
计划指南当然对主要有效,正如执行计划所证明的那样:
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)';
Run Code Online (Sandbox Code Playgroud)
此时我确实确认计划指南已复制到辅助服务器。
在辅助节点上运行相同的查询,执行计划缺少计划指南强制执行的所有迹象:
<StmtSimple StatementCompId="1" StatementEstRows="1000" ... StatementType="SELECT"
PlanGuideDB="..._UAT" PlanGuideName="plan-guide-test" ...>
Run Code Online (Sandbox Code Playgroud)