Форсирование плана хранилища запросов НЕ влияет на запросы на вторичном сервере.
Использование Query Store для принудительного создания плана на первичном сервере, безусловно, выглядит так, будто оно навязывает план вторичному.
Я попытался выполнить запрос на сервере, не sp_query_store_flush_db
являющемся продуктом, а затем очистить хранилище запросов (что было необходимо для синхронизации данных с дополнительным устройством). Вот вторичный слева (обратите внимание на обведенное кружком предупреждение о том, что он «только для чтения»), и первичный справа:
Теперь я нажму «Force Plan» справа, а затем обновлю оба представления:
Таким образом, «форсирование» по крайней мере переносится в базовые таблицы Query Store. Это имеет смысл, учитывая, что статьи, цитируемые в OP, указывают на то, что форсирование запросов должно оставаться на месте после аварийного переключения:
Вопрос: Будет ли QDS сохранять информацию плана FORCED при переключении базы данных с первичной реплики на вторичную реплику?
Ответ: Да, QDS хранит информацию о принудительном плане в таблице sys.query_store_plan, поэтому в случае сбоя вы продолжите видеть то же поведение на новом первичном сервере.
Но имеет ли место принудительное поведение ? Теперь я выполню один и тот же запрос на обоих серверах. На первичном, как и ожидалось, атрибуте «UsePlan» присутствует в плане XML:
<QueryPlan DegreeOfParallelism="1" MemoryGrant="11096" CachedPlanSize="288" CompileTime="82"
CompileCPU="78" CompileMemory="2104" UsePlan="true">
И в пользовательском интерфейсе:
На дополнительном сервере (обратите внимание на другое имя сервера) план не был принудительным . Вот тот же план 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">