Si un plan est forcé sur le principal dans un groupe de disponibilité, est-il appliqué aux requêtes exécutées sur un secondaire?
Je recherche des réponses qui couvrent les deux possibilités de forçage de plan:
J'ai lu ce qui suit qui suggère que les plans forcés QS ne sont pas reportés, mais je ne trouve rien d'autorité dans la documentation, ni rien sur les guides de plan.
Une preuve concluante du forçage serait la présence de Use Plan
ou PlanGuideName
et PlanGuideDB
propriétés dans le plan d'exécution du secondaire.
L'utilisation de Query Store pour forcer un plan sur le primaire semble ( forcer le plan sur le secondaire.
J'ai essayé d'exécuter une requête sur un serveur non prod, puis de vider le magasin de requêtes avec sp_query_store_flush_db
(qui était nécessaire pour synchroniser les données avec le secondaire). Voici le secondaire à gauche (notez l'avertissement encerclé d'être "en lecture seule"), et le principal à droite:
Maintenant, je clique sur "Forcer le plan" à droite, puis actualise les deux vues:
Ainsi, le "forçage" au moins a été reporté dans les tables de magasin de requêtes sous-jacentes. Cela est logique, étant donné que les articles cités dans l'OP font valoir que le forçage des requêtes doit rester en place après un basculement:
Question: QDS conservera-t-il les informations FORCED Plan lors du basculement de la base de données du réplica principal vers le réplica secondaire?
Réponse: Oui, QDS stocke les informations Forced Plan dans la table sys.query_store_plan, donc en cas de basculement, vous continuerez à voir le même comportement sur le nouveau serveur principal.
Mais le comportement de forçage a-t-il réellement lieu? Je vais maintenant exécuter la même requête sur les deux serveurs. Sur le primaire, comme prévu, l'attribut "UsePlan" est là dans le plan XML:
<QueryPlan DegreeOfParallelism="1" MemoryGrant="11096" CachedPlanSize="288" CompileTime="82"
CompileCPU="78" CompileMemory="2104" UsePlan="true">
Et dans l'interface utilisateur:
Sur le secondaire (notez le nom du serveur différent), le plan n'était pas forcé . Voici le même extrait de plan XML:
<QueryPlan DegreeOfParallelism="1" MemoryGrant="11096" CachedPlanSize="288" CompileTime="32"
CompileCPU="28" CompileMemory="1656">
J'ai créé un guide de plan sur le primaire en utilisant ce code (les noms de table ont été modifiés pour protéger les innocents):
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)';
Le guide du plan était, bien sûr, efficace sur le primaire, comme en témoigne le plan d'exécution:
<StmtSimple StatementCompId="1" StatementEstRows="1000" ... StatementType="SELECT"
PlanGuideDB="..._UAT" PlanGuideName="plan-guide-test" ...>
J'ai confirmé à ce stade que le guide de plan a été reproduit au secondaire.
En exécutant la même requête sur le secondaire, le plan d'exécution manque tous les signes d'être forcé par un guide de plan:
<StmtSimple StatementCompId="1" StatementEstRows="1000" ... StatementType="SELECT"
QueryHash="0xECF8A24F126EE77A" QueryPlanHash="0x0E93CF7FEAC1B6EA"
RetrievedFromCache="true" SecurityPolicyApplied="false">