Optimering av parameterkänslig plan

Gäller för: SQL Server 2022 (16.x) och senare versioner Azure SQL DatabaseAzure SQL Managed InstanceSQL Database i Microsoft Fabric

Psp-optimering (Parameter Sensitive Plan) är en del av den intelligenta frågebearbetningsfamiljen med funktioner. Den hanterar scenariot där en enda cachelagrad plan för en parameteriserad fråga inte är optimal för alla möjliga inkommande parametervärden. Detta gäller för icke-enhetliga datadistributioner. För mer information, se Parameterkänslighet och Parametrar och Återanvändning av exekveringsplan.

Mer information om befintliga lösningar för det här problemscenariot finns i:

PSP-optimering möjliggör automatiskt flera aktiva cachelagrade planer för en enda parameteriserad instruktion. Cachelagrade körningsplaner rymmer olika datastorlekar baserat på de kundspecifika körningsparametervärdena.

Förstå parameterisering

I Databasmotor för SQL Server ökar användningen av parametrar eller parametermarkörer i Transact-SQL -instruktioner (T-SQL) relationsmotorns möjlighet att matcha nya T-SQL-instruktioner med befintliga, tidigare kompilerade körningsplaner och främja planomutnytting. Mer information finns i Enkel parameterisering.

Du kan också åsidosätta standardbeteendet för enkel parameterisering för SQL Server genom att ange att alla SELECT, INSERT, UPDATEoch DELETE -instruktioner i en databas är parametriserade, med vissa begränsningar. Mer information finns i Tvingad parameterisering.

Implementering av PSP-optimering

Under den första kompileringen identifierar histogram för kolumnstatistik icke-enhetliga fördelningar och utvärderar de mest riskbelagda parametriserade predikaten, upp till tre av alla tillgängliga predikat. Med andra ord, om flera predikat i samma fråga uppfyller kriterierna väljer PSP-optimering de tre främsta. PSP-funktionen begränsar antalet predikat som utvärderas för att undvika att överbelasta plancachen och Query Store (om Query Store är aktiverat) med för många planer.

För berättigade planer skapar den första kompileringen en dispatcher-plan som innehåller PSP-optimeringslogik som kallas ett dispatcher-uttryck. En dispatcherplan kartlägger till frågevarianter baserat på predikaten för kardinalitetsområdets gränsvärden.

Terminology

Överordnad fråga

Den ursprungliga parameteriserade frågan för vilken PSP-optimering genererar en dispatcherplan och varianter av frågor. Frågevarianter är barnfrågor till föräldrafrågan. Query Store kan behålla mer än en dispatcher plan för samma parent query över tid.

Dispatcher-uttryck

Utvärderar kardinaliteten för predikat baserat på körningsparametervärden och dirigera körning till olika frågevarianter.

Dispatcherplan

En plan som innehåller dispatcher-uttrycket cachas för den ursprungliga parameteriserade frågan, även kallad föräldrafrågan. Dispatcherplanen är i princip en samling av de predikat som funktionen valt, med några extra detaljer. För varje valt predikat inkluderar dispatcherplanen de höga och låga gränsvärdena. Dessa värden delar in parametervärden i olika kategorier eller intervall. Dispatcher-planen innehåller också den statistik som användes för att beräkna gränsvärdena.

Frågevariant

När en dispatcher-plan utvärderar kardinaliteten för predikat baserat på värden från körningsparametrar, indelar den dessa värden i kategorier och genererar separata underordnade frågor för kompilering och körning. Dessa barnfrågor kallas frågevarianter. Frågevarianter har sina egna planer i plancachen och i Query Store.

Predikat kardinalitetsområde

Vid körning utvärderas kardinaliteten för varje predikat baserat på körningsparametervärden. Dispatcher delar in kardinalitetsvärdena i tre predikatkardinalitetsintervall vid kompileringstiden. Psp-optimeringsfunktionen kan till exempel skapa tre intervall som representerar låga, medelstora och höga kardinalitetsintervall, enligt följande diagram.

Diagram som visar gränserna för parameterkänslig plan.

Med andra ord, när en parametriserad fråga först kompileras genererar PSP-optimeringsfunktionen en skalplan som kallas för en dispatcher-plan. Dispatcher-uttrycket har logiken som bucketiserar frågor till frågevarianter baserat på körningsvärdena för parametrar. När den faktiska körningen börjar utför dispatchern två steg:

  • dispatchern utvärderar sitt dispatcher-uttryck för den angivna uppsättningen parametrar för att beräkna kardinalitetsintervallet.

  • dispatcher mappar dessa intervall till specifika frågevarianter och kompilerar och kör varianterna. Med hjälp av flera frågevarianter uppnår PSP-optimeringsfunktionen flera planer för en enda fråga.

Gränserna för kardinalitetsintervallet kan ses i ShowPlan XML för en leveransplan:

<Dispatcher>
  <ParameterSensitivePredicate LowBoundary="100" HighBoundary="1000000">
    <StatisticsInfo Database="[PropertyMLS]" Schema="[dbo]" Table="[Property]" Statistics="[NCI_Property_AgentId]" ModificationCount="0" SamplingPercent="100" LastUpdate="2019-09-07T15:32:16.89" />
    <Predicate>
      <ScalarOperator ScalarString="[PropertyMLS].[dbo].[Property].[AgentId]=[@AgentId]">
        <Compare CompareOp="EQ">
          <ScalarOperator>
            <Identifier>
              <ColumnReference Database="[PropertyMLS]" Schema="[dbo]" Table="[Property]" Column="AgentId" />
            </Identifier>
          </ScalarOperator>
          <ScalarOperator>
            <Identifier>
              <ColumnReference Column="@AgentId" />
            </Identifier>
          </ScalarOperator>
        </Compare>
      </ScalarOperator>
    </Predicate>
  </ParameterSensitivePredicate>
</Dispatcher>

Ett PSP-optimeringsgenererat tips läggs till i SQL-instruktionen i ShowPlan XML för en frågevariant. Tipset kan inte användas direkt och parsas inte om det läggs till manuellt. Tipset innehåller följande element:

option ( PLAN PER VALUE ( ObjectID = (int), QueryVariantID = (int), predicate_range ([databaseName].[schemaName].[tableName].[columnName] = @paramName, lowBoundaryValue, highBoundaryValue) ))

  • ObjectID kommer från modulen (dvs. lagrad procedur, funktion, utlösare) som den aktuella instruktionen är en del av; med antagandet att -instruktionen har genererats från en modul. Om -instruktionen är resultatet av dynamisk eller ad hoc SQL (dvs sp_executesql. ) är ObjectID-elementet lika med 0.
  • QueryVariantID motsvarar ungefär kombinationen av intervall för alla predikat som PSP-optimering har valt. Om en fråga till exempel har två predikat som är berättigade till PSP och varje predikat har tre intervall, kommer det att finnas nio frågevariantintervall numrerade 1–9.
  • predikatintervallet är den predikaterade kardinalitetsintervallinformationen som genereras från dispatcher-uttrycket.

Och inom ShowPlan XML för en frågevariant (inom Dispatcher-elementet):

<Batch>
  <Statements>
    <StmtSimple StatementText="SELECT PropertyId,&#xD;&#xA;       AgentId,&#xD;&#xA;       MLSLinkId,&#xD;&#xA;       ListingPrice,&#xD;&#xA;       ZipCode,&#xD;&#xA;       Bedrooms,&#xD;&#xA;       Bathrooms&#xD;&#xA;FROM dbo.Property&#xD;&#xA;WHERE AgentId = @AgentId&#xD;&#xA;ORDER BY ListingPrice DESC option (PLAN PER VALUE(ObjectID = 613577224, QueryVariantID = 1, predicate_range([PropertyMLS].[dbo].[Property].[AgentId] = @AgentId, 100.0, 1000000.0)))" StatementId="1" StatementCompId="2" StatementType="SELECT" StatementSqlHandle="0x090085E4372DFC69BB9E7EBA421561DE8E1E0000000000000000000000000000000000000000000000000000" DatabaseContextSettingsId="1" ParentObjectId="0" StatementParameterizationType="1" RetrievedFromCache="false" StatementSubTreeCost="0.021738" StatementEstRows="3" SecurityPolicyApplied="false" StatementOptmLevel="FULL" QueryHash="0x476167A000F589CD" QueryPlanHash="0xDE982107B7C28AAE" StatementOptmEarlyAbortReason="GoodEnoughPlanFound" CardinalityEstimationModelVersion="160">
      <StatementSetOptions QUOTED_IDENTIFIER="true" ARITHABORT="true" CONCAT_NULL_YIELDS_NULL="true" ANSI_NULLS="true" ANSI_PADDING="true" ANSI_WARNINGS="true" NUMERIC_ROUNDABORT="false" />

      <Dispatcher>
        <ParameterSensitivePredicate LowBoundary="100" HighBoundary="1e+06">
          <StatisticsInfo LastUpdate="2019-09-07T15:32:16.89" ModificationCount="0" SamplingPercent="100" Statistics="[NCI_Property_AgentId]" Table="[Property]" Schema="[dbo]" Database="[PropertyMLS]" />
          <Predicate>
            <ScalarOperator ScalarString="[PropertyMLS].[dbo].[Property].[AgentId]=[@AgentId]">
              <Compare CompareOp="EQ">
                <ScalarOperator>
                  <Identifier>
                    <ColumnReference Database="[PropertyMLS]" Schema="[dbo]" Table="[Property]" Column="AgentId" />
                  </Identifier>
                </ScalarOperator>
                <ScalarOperator>
                  <Identifier>
                    <ColumnReference Column="@AgentId" />
                  </Identifier>
                </ScalarOperator>
              </Compare>
            </ScalarOperator>
          </Predicate>
        </ParameterSensitivePredicate>
      </Dispatcher>

    </StmtSimple>
  </Statements>
</Batch>

Remarks

  • Från och med SQL Server 2025 (17.x) och databaskompatibilitet 170 innehåller PSP-optimering följande fyra förbättringar:

    • Stöd för data manipulation language (DML)-satser såsom DELETE, INSERT, , MERGEoch UPDATE.
    • Utökat stöd för tempdb.
    • Stöd för att välja flera giltiga predikat från samma tabell, med högst ett predikat valt per kolumn.
    • Ändringar i den query_with_parameter_sensitivity utökade händelsen som inkluderade fälten interesting_predicate_count, max_skewness, psp_optimization_supported och query_type före ändringarna i SQL Server 2025 (17.x) och databaskompatibilitet 170. Men ta nu med fälten interesting_predicate_count, interesting_predicate_details, psp_optimization_supported och query_type. Mer information finns i avsnittet Utökade händelser .
  • PSP-optimeringsfunktionen fungerar för närvarande endast med likhetspredikat.

  • Dispatcherplaner återskapas automatiskt om det sker betydande ändringar i datadistributionen. Frågevariantplaner rekompileras oberoende vid behov, precis som andra frågeplanstyper, beroende på standardhändelser för omkompilering. Mer information om rekompilering finns i Rekompilera exekveringsplaner.

  • Systemkatalogvyn sys.query_store_plan för Query Store har ändrats för att skilja mellan en normalt kompilerad plan, en dispenserplan och en frågevariantplan. Den nya systemkatalogvyn för Query Store, sys.query_store_query_variant, innehåller information om förhållandet mellan de ursprungliga parametriserade frågorna (även kända som föräldrafrågor), distributionsplaner och deras underordnade frågevarianter.

  • På databaskompatibilitetsnivå 160, när det finns flera giltiga predikat som ingår i samma tabellreferens, väljer PSP-optimering det predikat som har mest dataskevhet baserat på det underliggande statistikhistogrammet. Till exempel, med SELECT * FROM table1 WHERE column1 = @predicate1 AND column2 = @predicate2, väljs endast det mest snedvridna predikatet eftersom båda predikaten refererar till samma tabell. Om frågan dock refererar till tabellen mer än en gång, till exempel i separata grenar av en UNION eller genom aliaser i en själv-join, kan PSP-optimering välja predikat från mer än en tabellreferens.

  • Från och med SQL Server 2025 (17.x) och databaskompatibilitetsnivå 170 kan PSP-optimering välja flera kvalificerade predikat från samma tabell. Endast ett predikat per kolumn väljs, och det totala antalet predikat som väljs för frågan förblir begränsat till tre. Till exempel, med SELECT * FROM table1 WHERE column1 = @predicate1 AND column2 = @predicate2, kan båda predikaten väljas om de uppfyller kriterierna för PSP-optimering.

  • ShowPlan XML för en frågevariant skulle se ut ungefär som i följande exempel, där båda predikaten som valts har sin respektive information tillagd till den PLAN PER VALUE PSP-relaterade ledtråden.

    <Batch>
      <Statements>
        <StmtSimple StatementText="SELECT  b.PropertyId, &#xD;&#xA;       AgentId, &#xD;&#xA;       MLSLinkId, &#xD;&#xA;       ListingPrice, &#xD;&#xA;       ZipCode, &#xD;&#xA;       Bedrooms, &#xD;&#xA;       Bathrooms &#xD;&#xA;FROM dbo.AgentProperty a join  PropertyDetails b on a.PropertyId = b.PropertyId&#xD;&#xA;WHERE AgentId = @AgentId and  Property_id=@Property_id&#xD;&#xA;UNION&#xD;&#xA;          SELECT  c.PropertyId, &#xD;&#xA;       AgentId, &#xD;&#xA;       MLSLinkId, &#xD;&#xA;       ListingPrice, &#xD;&#xA;       ZipCode, &#xD;&#xA;       Bedrooms, &#xD;&#xA;       Bathrooms &#xD;&#xA;FROM dbo.AgentProperty c join  PropertyDetails d on c.PropertyId = d.PropertyId&#xD;&#xA;WHERE AgentId = @AgentId and  Property_id=@Property_id option (PLAN PER VALUE(ObjectID = 981578535, QueryVariantID = 9, predicate_range([PropertyMLS].[dbo].[AgentProperty].[AgentId] = @AgentId, 100.0, 1000000.0),predicate_range([PropertyMLS].[dbo].[AgentProperty].[AgentId] = @AgentId, 100.0, 1000000.0)))" StatementId="1" StatementCompId="2" StatementType="SELECT" StatementSqlHandle="0x090051FBCD918F8DFD60D324887356B422D90000000000000000000000000000000000000000000000000000" DatabaseContextSettingsId="2" ParentObjectId="0" StatementParameterizationType="1" RetrievedFromCache="false" StatementSubTreeCost="29.2419" StatementEstRows="211837" SecurityPolicyApplied="false" StatementOptmLevel="FULL" QueryHash="0x6D2A4E407085C01E" QueryPlanHash="0x72101C0A0DD861AB" CardinalityEstimationModelVersion="160" BatchModeOnRowStoreUsed="true">
          <StatementSetOptions QUOTED_IDENTIFIER="true" ARITHABORT="true" CONCAT_NULL_YIELDS_NULL="true" ANSI_NULLS="true" ANSI_PADDING="true" ANSI_WARNINGS="true" NUMERIC_ROUNDABORT="false" />
          <Dispatcher>
            <ParameterSensitivePredicate LowBoundary="100" HighBoundary="1e+06">
              <StatisticsInfo LastUpdate="2022-08-11T20:42:35.02" ModificationCount="0" SamplingPercent="100" Statistics="[NCI_AgentProperty_AgentId]" Table="[AgentProperty]" Schema="[dbo]" Database="[PropertyMLS]" />
              <Predicate>
                <ScalarOperator ScalarString="[PropertyMLS].[dbo].[AgentProperty].[AgentId] as [a].[AgentId]=[@AgentId]">
                  <Compare CompareOp="EQ">
                    <ScalarOperator>
                      <Identifier>
                        <ColumnReference Database="[PropertyMLS]" Schema="[dbo]" Table="[AgentProperty]" Alias="[a]" Column="AgentId" />
                      </Identifier>
                    </ScalarOperator>
                    <ScalarOperator>
                      <Identifier>
                        <ColumnReference Column="@AgentId" />
                      </Identifier>
                    </ScalarOperator>
                  </Compare>
                </ScalarOperator>
              </Predicate>
            </ParameterSensitivePredicate>
            <ParameterSensitivePredicate LowBoundary="100" HighBoundary="1e+06">
              <StatisticsInfo LastUpdate="2022-08-11T20:42:35.02" ModificationCount="0" SamplingPercent="100" Statistics="[NCI_AgentProperty_AgentId]" Table="[AgentProperty]" Schema="[dbo]" Database="[PropertyMLS]" />
              <Predicate>
                <ScalarOperator ScalarString="[PropertyMLS].[dbo].[AgentProperty].[AgentId] as [c].[AgentId]=[@AgentId]">
                  <Compare CompareOp="EQ">
                    <ScalarOperator>
                      <Identifier>
                        <ColumnReference Database="[PropertyMLS]" Schema="[dbo]" Table="[AgentProperty]" Alias="[c]" Column="AgentId" />
                      </Identifier>
                    </ScalarOperator>
                    <ScalarOperator>
                      <Identifier>
                        <ColumnReference Column="@AgentId" />
                      </Identifier>
                    </ScalarOperator>
                  </Compare>
                </ScalarOperator>
              </Predicate>
            </ParameterSensitivePredicate>
          </Dispatcher>
          <QueryPlan CachedPlanSize="160" CompileTime="17" CompileCPU="17" CompileMemory="1856" QueryVariantID="9">
    
  • Du kan påverka de aktuella tröskelvärdena för skevhet som används av PSP-optimeringsfunktionen med en eller flera av följande metoder:

    • Spårningsflaggor för kardinalitetsestimator (CE), till exempel spårningsflagga 9481 (global, session eller frågenivå)

    • Databasomfattande konfigurationsalternativ som försöker sänka CE-modellen som används eller påverka de antaganden som CE-modellen gör när det gäller oberoendet för flera predikater. Detta är särskilt användbart i fall där statistik med flera kolumner inte finns, vilket påverkar PSP-optimeringens förmåga att utvärdera kandidaturen för dessa predikater.

    • Mer information finns i avsnittet Increased Correlation Assumption for Multiple Predicates (Ökat korrelationsantagande för flera predikater) i vitboken Optimera dina frågeplaner med SQL Server 2014 Cardinality Estimator . Den nyare CE-modellen försöker anta en viss korrelation och mindre oberoende för konjunktion och disjunktion av predikat. Användning av den äldre CE-modellen kan påverka hur selektiviteten för predikaten i ett scenario med flera kolumner kan beräknas. Den här åtgärden bör endast övervägas för specifika scenarier och vi rekommenderar inte att du använder den äldre CE-modellen för de flesta arbetsbelastningar.

  • PSP-optimering kompilerar och exekverar varje frågevariant som ett separat prepared statement. Queryvariantplaner kan cachelagras och återanvändas, så en ny kompilering krävs inte för varje körning. Eftersom frågevarianter är separata förberedda satser, identifierar deras plancachevärden object_id inte föräldramodulen om föräldrafrågan är en del av en modul (det vill säga lagrad procedur, trigger, funktion och så vidare). För en förberedd instruktion är plancachen object_id i princip ett beräknat värde baserat på en intern hash av batchtexten, snarare än ID:t för ett objekt i sys.objects. Mer information finns i avsnittet Returnerad tabell i sys.dm_exec_plan_attributes DMV-dokumentationen.

    Frågevariationsplaner lagras i cachelagret SQL Plans (CACHESTORE_SQLCP). Dispatcherplanen förblir en del av den ursprungliga batchens eller modulens cachelagrade plan. Om föräldrafrågan är en del av en lagrad procedur eller en annan modul vars kompilerade plan lagras i Object Plans cache-lagring (CACHESTORE_OBJCP), lagras dispatcherplanen i CACHESTORE_OBJCP. Om föräldrafrågan är en del av en parameteriserad dynamisk SQL- eller kvalificerad ad hoc-batch, lagras dispatcherplanen i CACHESTORE_SQLCP.

    PSP-funktionen lagrar en object_id för en frågevariants överordnade modul inom attributet ObjectID, som är en del av ledtråden PLAN PER VALUE i ShowPlan XML. Om föräldrafrågan är dynamisk eller ad hoc T-SQL, är detta attribut 0. Sammanställd prestandastatistik för cachelagrade procedurer, funktioner och utlösare kan fortsätta att användas för respektive ändamål. Mer detaljerad exekveringsrelaterad statistik, såsom den som finns i sys.dm_exec_query_stats DMV, innehåller fortfarande data för frågevarianter. Att associera dessa statistik med en föräldramodul kräver dock ytterligare bearbetning av ShowPlan XML, eftersom frågevariantens plancache object_id inte direkt identifierar föräldramodulen. Körtids- och väntestatistik för frågevarianter kan erhållas från Query Store utan ytterligare ShowPlan XML-parsning om Query Store är aktiverad.

  • Modermodulens objekt-ID exponeras inte direkt som frågevariantens object_id i plan cache-relaterade sys.dm_exec_* DMV:er. Den cachade modulplanen som innehåller dispatchern behåller modulens objekt-ID. För frågevarianter kan föräldramodulens objekt-ID erhållas från attributet ObjectID i PLAN PER VALUE hinten genom att bearbeta ShowPlan XML. Query Store tillhandahåller en relationsmodell för att identifiera dessa relationer. sys.query_store_query_variant katalogvyn anger den ursprungliga parameteriserade frågan med parent_query_id, dispatcherplanen med dispatcher_plan_id och den underordnade frågan med query_variant_query_id.

Considerations

  • För att aktivera PSP-optimering, använd databaskompatibilitetsnivå 160 eller högre för den databas du är ansluten till när du kör frågan. PSP-optimeringsförbättringarna som introducerades i SQL Server 2025 (17.x) kräver databaskompatibilitetsnivå 170 eller högre.

  • För ytterligare insikter om PSP-optimeringsfunktionen rekommenderar vi att Query Store-integrering aktiveras genom att aktivera Query Store. I följande exempel aktiveras Query Store för en befintlig databas med namnet MyNewDatabase:

ALTER DATABASE [MyNewDatabase]
SET QUERY_STORE = ON (
    OPERATION_MODE = READ_WRITE,
    QUERY_CAPTURE_MODE = AUTO
);

Note

Från och med SQL Server 2022 (16.x) är Query Store nu aktiverat som standard för alla nyligen skapade databaser.

  • Om du vill inaktivera PSP-optimering på databasnivå använder du konfigurationen ALTER DATABASE SCOPED CONFIGURATION SET PARAMETER_SENSITIVE_PLAN_OPTIMIZATION = OFF med databasomfattning.

  • Om du vill inaktivera PSP-optimering på frågenivå använder du frågetipset DISABLE_PARAMETER_SENSITIVE_PLAN .

  • Om parametersniffning inaktiveras av spårningsflagga 4136, PARAMETER_SNIFFING databasomfattande konfiguration eller USE HINT('DISABLE_PARAMETER_SNIFFING') frågetipset inaktiveras PSP-optimering för associerade arbetsbelastningar och körningskontexter. Mer information finns i Frågetips och ALTER DATABASE SCOPED CONFIGURATION.

  • Antalet unika planvarianter per dispatcher som lagras i plancachen är begränsat för att undvika överbelastning av cachen. Det interna tröskelvärdet är inte dokumenterat. Eftersom varje SQL-batch har potential att skapa flera planer, och varje frågevariantplan har en oberoende post i plancachen, är det möjligt att nå det maximala standardantalet tillåtna planposter. Om borttagningshastigheten för plancache är märkbart hög eller om storlekarna på CACHESTORE_OBJCPCACHESTORE_SQLCP är för stora, bör du överväga att använda spårningsflagga 174.

  • Antalet unika planvarianter som lagras för en fråga i Query Store-arkivet begränsas av konfigurationsalternativet max_plans_per_query . Eftersom frågevarianter kan ha fler än en plan kan totalt 200 planer finnas per fråga i Query Store. Det här talet innehåller alla frågevariantplaner för alla dispatchers som tillhör en överordnad fråga. Överväg att öka konfigurationsalternativet max_plans_per_query för Query Store.

    • Ett exempel på hur antalet unika planer kan överskrida standardgränsen för Query Store max_plans_per_query är ett scenario där du har följande beteende. Anta att du har en fråga med fråge-ID:t 10, som har två dispatcher-planer och varje dispatcher-plan har 20 frågevarianter vardera (totalt 40 frågevarianter). Det totala antalet planer för fråge-ID 10 är 40 planer för frågevarianterna och de två dispatcher-planerna. Det är också möjligt att den överordnade frågan (fråge-ID 10) kan ha 5 vanliga (icke-dispatcher)-planer. Detta gör 47 planer (40 från frågevarianter, 2 dispatcher och 5 icke-PSP-relaterade planer). Om varje frågevariant också har ett genomsnitt på fem planer är det dessutom möjligt i det här scenariot att ha fler än 200 planer i Query Store för en överordnad fråga. Detta beror också på stora datasnedvridningar i datauppsättningarna som den överordnade exempelfrågan kan referera till.
  • För varje frågevariantmappning till en viss dispatcher:

    • Den query_plan_hash är unik. Den här kolumnen är tillgänglig i sys.dm_exec_query_stats, och andra dynamiska hanteringsvyer och katalogtabeller.
    • Den plan_handle är unik. Den här kolumnen är tillgänglig i sys.dm_exec_query_stats, sys.dm_exec_sql_text, sys.dm_exec_cached_plansoch i andra dynamiska hanteringsvyer och funktioner samt katalogtabeller.
    • query_hash Är vanligt för andra varianter som mappas till samma dispatcher, så det är möjligt att fastställa aggregerad resursanvändning för frågor som endast skiljer sig åt med indataparametervärden. Den här kolumnen är tillgänglig i sys.dm_exec_query_stats, sys.query_store_queryoch andra dynamiska hanteringsvyer och katalogtabeller.
    • sql_handle Är unikt på grund av att särskilda PSP-optimeringsidentifierare läggs till i frågetexten under kompilering. Den här kolumnen är tillgänglig i sys.dm_exec_query_stats, sys.dm_exec_sql_text, sys.dm_exec_cached_plansoch i andra dynamiska hanteringsvyer och funktioner samt katalogtabeller. Samma referensinformation är tillgänglig i Query Store som kolumnen last_compile_batch_sql_handle i katalogtabellen sys.query_store_query.
    • query_id är unikt i Query Store. Den här kolumnen är tillgänglig i sys.query_store_query, och andra Query Store-katalogtabeller.

Planera framtvingande i Query Store

Använder samma sp_query_store_force_plan och sp_query_store_unforce_plan lagrade procedurer för att hantera dispatcher- och variantplaner.

Om du tvingar fram en query variant-plan, tvingar du inte dess tillhörande dispatcherplan. Om en dispatcher tvingas, kommer endast varianter från den dispatchern att anses godkända för användning.

  • Tidigare framtvingade varianter från andra distributörer blir inaktiva men behåller den framtvingade statusen tills deras distributör tvingas igen
  • De varianter som tidigare hade tvingats fram i samma dispatcher och blivit inaktiva tvingas fram igen.

Frågebutikens frågetipsbeteende

  • När ett Query Store-tips läggs till i en frågevariant (underordnad fråga) tillämpas tipset på samma sätt som en icke-PSP-fråga. Frågevarianttips har högre prioritet om ett tips också har tillämpats på den överordnade frågan i Query Store.

  • När ett Query Store-tips läggs till i den överordnade frågan och den underordnade frågan (frågevarianten) inte har ett befintligt Query Store-tips ärver den underordnade frågan (frågevarianten) tipset från den överordnade frågan.

  • Om ett frågetips för Query Store tas bort från den överordnade frågan tas även de underordnade frågorna (frågevarianterna) bort.

  • Om en RECOMPILE ledtråd läggs till i huvudfrågan genererar systemet icke-PSP-planer efter att befintliga frågevariantplaner har tagits bort från plancachen, eftersom PSP-funktionen inte fungerar på frågor som har en RECOMPILE ledtråd.

  • Frågearkivets tipsresultat kan observeras med hjälp av utökade händelser query_store_hints_application_success och query_store_hints_application_failed händelser. För tabellen sys.query_store_query_hints innehåller den information om frågetipset som har tillämpats. Om tipset bara har tillämpats på en överordnad fråga innehåller systemkatalogen tipsinformationen för den överordnade frågan, men inte för dess underordnade frågor, även om de underordnade frågorna ärver den överordnade frågans tips.

PSP med frågehintar och planforceringsbeteende kan sammanfattas i följande tabell:

Förslag eller plan för frågevariant Förälder har användartillämpad tips. Förälder har tillämpat feedback-ledtråd Överordnad har manuellt framtvingad plan Överordnad har en framtvingad APC 1-plan
Tips via användare Förslag för sökfrågevariant Förslag för sökfrågevariant Förslag för sökfrågevariant N/A
Tips via feedback Förslag för sökfrågevariant Förslag för sökfrågevariant Förslag för sökfrågevariant N/A
Plan framtvingad av användare Frågevariant
tvingad plan
Frågevariant
tvingad plan
Frågevariant
tvingad plan
Frågevariant
tvingad plan
Plan framtvingad av APC Frågevariant
tvingad plan
Frågevariant
tvingad plan
Frågevariant
tvingad plan
Frågevariant
tvingad plan
Ingen ledtråd eller tvingad plan Överordnad användares tips Ingen ledtråd Ingen åtgärd Ingen åtgärd

1 Automatisk plankorrigeringskomponent för funktionen för automatisk justering

Utökade händelser

  • parameter_sensitive_plan_optimization_skipped_reason: Inträffar när funktionen för parameterkänslig plan hoppas över. Använd den här händelsen för att övervaka orsaken till att PSP-optimering hoppar över.

    Följande fråga visar alla möjliga orsaker till varför PSP hoppades över:

    SELECT map_value
    FROM sys.dm_xe_map_values
    WHERE [name] = 'psp_skipped_reason_enum'
    ORDER BY map_key;
    
  • parameter_sensitive_plan_optimization: Inträffar när en fråga använder PSP-optimeringsfunktionen. Endast felsökningskanal. Vissa intressanta områden kan vara:

    • is_query_variant: beskriver om det här är en dispatcher-plan (överordnad) eller en frågevariantplan (underordnad)
    • predicate_count: antal predikater som valts av PSP
    • query_variant_id: visar frågevariant-ID:t. Värdet 0 innebär att objektet är en dispatcher-plan (överordnad).
  • query_with_parameter_sensitivity: Den här händelsen när den utlöses visar antalet predikat som funktionen fann intressant, mer information i json-format om de intressanta predikaten, samt om PSPO stöds för predikatet eller predikaten.

  • Exempel på utdata från den query_with_parameter_sensitivity utökade händelsen

Field Value
interesting_predicate_count 3
interesting_predicate_details {"Predicates":[{"ColumnId":7,"TableId":1221579390,"Skewness":475038.75},{"ColumnId":7,"TableId":1221579390,"Skewness":475038.75},{"ColumnId":7,"TableId":1221579390,"Skewness":475038.75}]}
psp_optimization_supported True
query_type 195

SQL Server-granskningsbeteende

PSP-optimering tillhandahåller granskningsdata för dispatcher-planinstruktionen och de eventuella frågevarianter som är associerade med dispatchern. Kolumnen additional_information i SQL Server Audit innehåller också lämplig T-SQL-stackinformation för frågevarianter. Om databasen MyNewDatabase till exempel har en tabell med namnet T2 och en lagrad procedur med namnet , efter körningen av usp_testden usp_test lagrade proceduren, kan granskningsloggen innehålla följande poster:

action_id object_name statement additional_information
AUSC <action_info xmlns="http://schemas.microsoft.com/sqlserver/2008/sqlaudit_data"><session><![CDATA[Audit_Testing_Psp$A]]></session><action>event enabled</action><startup_type>manual</startup_type><object><![CDATA[audit_event]]></object></action_info>
EX usp_test exec usp_test 300
SL T2 välj * från dbo.t2 där ID=@id <tsql_stack><frame nest_level = '1' database_name = 'MyNewDatabase' schema_name = 'dbo' object_name = 'usp_test'/></tsql_stack>
SL T2 välj * från dbo.t2 där ID=@id alternativ (PLAN PER VALUE(ObjectID = 933578364, QueryVariantID = 1, predicate_range([MyNewDatabase].[dbo].[T2].[ID] = @id, 100.0, 100000.0))) tsql_stack><frame nest_level = '1' database_name = 'MyNewDatabase' schema_name = 'dbo' object_name = 'usp_test'/></tsql_stack>
EX usp_test exec usp_test 60000
SL T2 välj * från dbo.t2 där ID=@id <tsql_stack><frame nest_level = '1' database_name = 'MyNewDatabase' schema_name = 'dbo' object_name = 'usp_test'/></tsql_stack>
SL T2 välj * från dbo.t2 där ID=@id option (PLAN PER VALUE(ObjectID = 933578364, QueryVariantID = 3, predicate_range([TestDB_FOR_PSP].[dbo].[T2].[ID] = @id, 100.0, 100000.0))) <tsql_stack><frame nest_level = '1' database_name = 'MyNewDatabase' schema_name = 'dbo' object_name = 'usp_test'/></tsql_stack>

Kända problemområden

Issue Identifierat datum Status Datum åtgärdat
Undantag för åtkomstöverträdelse inträffar i Query Store i SQL Server 2022 (16.x) under vissa villkor. Du kan stöta på åtkomstöverträdelseundantag när PSP-optimeringsintegration med Query Store är aktiverad. Mer information finns i uppdateringen i Parameterkänslig planoptimering, Varför? mars 2023 Resolved Augusti 2023 (SQL Server 2022 CU 7)
Undantag för åtkomstöverträdelse kan inträffa på läsbara sekundära repliker under vissa villkor i SQL Server 2025 (17.x). Du kan stöta på undantag för åtkomstöverträdelser när PSP-optimering är aktiverad på en läsbar sekundär databas som har konfigurerats för att använda Query Store för läsbara sekundära repliker. 2025 september Resolved Januari 2026 (SQL Server 2025 CU 1)

Resolved

Undantag för åtkomstöverträdelse kan inträffa på läsbara sekundära repliker under vissa villkor

(Löst i januari 2026)

Frågor som uppfyller följande villkor kan uppleva en åtkomstöverträdelse när en frågevariant för parameterkänslig plan (PSP) inte kan fastställa det bevarade tillståndet för dess överordnade dispatcher-instruktion:

  • Körs på en sekundär replik
  • Känslig för parametersniffning
  • Berättigad till optimering av parameterkänslig plan (PSP)

Undantag för åtkomstöverträdelse inträffar i Query Store i SQL Server 2022 under vissa villkor

(Löst i mars 2023)

Note

SQL Server 2022 (16.x) Kumulativ uppdatering 7 innehåller flera korrigeringar för ett tävlingstillstånd som kan leda till en åtkomstöverträdelse.

Det här problemet inträffade på grund av ett konkurrenstillstånd som kan orsakas när körningsstatistiken för en körd fråga i Query Store sparas från minnesrepresentationen av Query Store (finns i minnesarkivet MEMORYCLERK_QUERYDISKSTORE_HASHMAP) till diskversionen av Query Store. Körningsstatistiken, som visas som Körningsstatistik, sparas i minnet under en tidsperiod, definierad av DATA_FLUSH_INTERVAL_SECONDS alternativet för -instruktionen SET QUERY_STORE (standardvärdet är 15 minuter). Du kan använda dialogrutan Management Studio Query Store för att ange ett värde för dataspolningsintervall (minuter), som konverteras internt till sekunder. Om systemet är under minnesbelastning kan körningsstatistik rensas till disken tidigare än vad som definierats med DATA_FLUSH_INTERVAL_SECONDS alternativet. När ytterligare Query Store-bakgrundstrådar relaterade till borttagning av frågeplaner i Query Store (d.v.s STALE_QUERY_THRESHOLD_DAYS och/eller MAX_STORAGE_SIZE_MB Query Store-alternativ) utför frågor från Query Store, finns det ett scenario där en frågevariant och/eller dess associerade dispatcher-instruktion kan avrefereras för tidigt. Detta kan leda till en åtkomstöverträdelse vid infogning eller borttagning av frågevarianter i Query Store.

Mer information om Query Store-åtgärder finns i avsnittet Anmärkningar i artikeln Hur Query Store samlar in data.