web-dev-qa-db-fra.com

Plans forcés sur des secondaires lisibles

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.

14
Paul White 9

Le forçage du plan du magasin de requêtes N'affecte PAS les requêtes sur le 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:

screenshot of query store UI

Maintenant, je clique sur "Forcer le plan" à droite, puis actualise les deux vues:

screenshot of query store UI showing both forced plans

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:

screenshot of execution plan in SSMS showing the "use plan" attribute

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">

screenshot of execution plan in SSMS showing the no "use plan" attribute

Les guides de plan n'affectent PAS les requêtes sur le secondaire

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" ...>

screenshot of execution plan in SSMS showing plan guide attributes

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">

screenshot of execution plan in XML with missing plan guide attributes

18
Josh Darnell