Dela via


Anvisningar för Query Store

gäller för: SQL Server 2022 (16.x) Azure SQL DatabaseAzure SQL Managed InstanceSQL-databas i Microsoft Fabric

Den här artikeln beskriver hur du använder frågetips med hjälp av Query Store. Query Store-tips är en lätthanterad metod för att forma frågeplaner utan att ändra programkod.

Query Store-tips är tillgängliga i Azure SQL Database och Azure SQL Managed Instance. Query Store-tips är också en funktion som introduceras för SQL Server i SQL Server 2022 (16.x).

Försiktighet

Eftersom SQL Server Query Optimizer vanligtvis väljer den bästa körningsplanen för en fråga rekommenderar vi att du bara använder tips som en sista utväg för erfarna utvecklare och databasadministratörer. Mer information finns i Frågetips.

Titta på den här videon för en översikt över Query Store-tips:

Överblick

Helst väljer frågeoptimeraren en optimal exekveringsplan för en fråga.

Om en optimal plan inte har valts kanske en utvecklare eller DBA vill optimera manuellt för specifika villkor. Frågetips anges via OPTION-satsen och kan användas för att påverka frågekörningsbeteendet. Frågetips hjälper till att tillhandahålla lokaliserade lösningar på olika prestandarelaterade problem, men de kräver en omskrivning av den ursprungliga frågetexten. Databasadministratörer och utvecklare kanske inte alltid kan göra ändringar direkt i Transact-SQL kod för att mata in ett frågetips. Transact-SQL kan hårdkodas i ett program eller genereras automatiskt av programmet. Tidigare kan en utvecklare behöva förlita sig på planguider, vilket kan vara komplext att använda.

Information om vilka frågetips som kan användas finns i frågetips som stöds.

När du ska använda Query Store-tips

Den här funktionen utökar och är beroende av Query Store, som namnet antyder. Query Store möjliggör insamling av frågeförfrågningar, exekveringsplaner och associerad körningsstatistik. Query Store förenklar kundupplevelsen för övergripande prestandajustering avsevärt. SQL Server 2016 (13.x) introducerade först Query Store, och nu är det aktiverat som standard i SQL Server 2022 (16.x), Azure SQL Managed Instance och Azure SQL Database.

Arbetsflödet för Query Store-hanteringstips.

Först körs frågan och registreras sedan av Query Store. Sedan skapar DBA ett Query Store-tips för en fråga. Därefter körs frågan med hjälp av anvisningen för Query Store.

Exempel där Query Store-tips kan hjälpa dig med prestandaproblem på frågenivå:

  • Kompilera om en fråga för varje körning.
  • Begränsa storleken på minnestilldelningen för en bulk-införingsoperation.
  • Begränsa den maximala graden av parallellitet vid uppdatering av statistik.
  • Använd en Hash-koppling i stället för en kapslad loopkoppling.
  • Använd kompatibilitetsnivå 110 för en specifik fråga samtidigt som du behåller allt annat i databasen på kompatibilitetsnivå 150.
  • Inaktivera radmålsoptimering för en SELECT TOP-fråga.

Så här använder du Query Store-tips:

  1. Identifiera Query Store-query_id för frågeuttryck som du vill ändra. Du kan göra detta på olika sätt:
    • Köra frågor mot Query Store-katalogvyer.
    • Använda inbyggda Query Store-rapporter i SQL Server Management Studio.
    • Använda Azure Portal Query Performance Insight för Azure SQL Database.
  2. Kör sys.sp_query_store_set_hints med den query_id- och frågetipssträng som du vill tillämpa på frågan. Den här strängen kan innehålla en eller flera frågetips. Fullständig information finns i sys.sp_query_store_set_hints.

När det har skapats bevaras Query Store-tips och klarar omstarter och driftavbrott. Query Store-tips åsidosätter hårdkodade tips på instruktionsnivå och befintliga tips i planguiden.

Om ett frågetips motsäger vad som är möjligt för sökfrågeoptimering blockeras inte frågekörningen, men tipset tillämpas inte. I de fall där ett tips skulle orsaka att en fråga misslyckas ignoreras tipset och den senaste felinformationen kan visas i sys.query_store_query_hints.

Lagrade procedurer för Query Store-hintsystemet

Om du vill skapa eller uppdatera tips använder du sys.sp_query_store_set_hints. Tips ska anges i ett giltigt strängformat N'OPTION (...)'.

  • När du skapar ett Query Store-tips skapas ett nytt Query Store-tips om det inte finns någon Query Store-ledtråd för en viss query_id.
  • När du skapar eller uppdaterar ett Query Store-tips, om det redan finns ett Query Store-tips för en specifik query_idåsidosätter det senaste angivna värdet tidigare angivna värden för den associerade frågan.
  • Om det inte finns någon query_id utlöses ett fel.

Not

En fullständig lista över tips som stöds finns i sys.sp_query_store_set_hints.

Om du vill ta bort tips som är associerade med en query_idanvänder du sys.sp_query_store_clear_hints.

XML-attribut för körningsplan

När ledtrådar tillämpas visas följande resultatuppsättning i StmtSimple-elementet i -körningsplanen i XML-format:

attribut Beskrivning
QueryStoreStatementHintText Faktiska Query Store-hintar som tillämpas på frågan
QueryStoreStatementHintId Unik identifierare för ett frågetips
QueryStoreStatementHintSource Källa till Query Store-hint (till exempel "Användare")

Anteckning

Dessa XML-element är tillgängliga via utdata från Transact-SQL-kommandona SET STATISTICS XML och SET SHOWPLAN XML.

Query Store-tips och funktionskompatibilitet

  • Query Store-hintar åsidosätter andra hårdkodade uttalsnivå-hintar och planguider.
  • Sökfrågor körs alltid. Motsatta Query Store-tips ignoreras som annars skulle orsaka ett fel.
  • Om Query Store-hints motsäger varandra, blockeras inte frågekörning i SQL Server, och Query Store-hinten tillämpas inte.
  • Enkel parameterisering – Query Store-tips stöds inte för instruktioner som är kvalificerade för enkel parameterisering.
  • Tvingad parameterisering – RECOMPILE-tipset är inte kompatibelt med tvingad parameterisering som angetts på databasnivå. Om databasen har en tvingad parameteriseringsuppsättning och RECOMPILE-tipset är en del av tipssträngen som angetts i Query Store för en fråga, ignorerar SQL Server RECOMPILE-tipset och tillämpar eventuella andra tips om de tillämpas.
    • Dessutom utfärdar SQL Server en varning (felkod 12461) som anger att RECOMPILE-tipset ignorerades.
    • Mer information om användningsfallsöverväganden för tvingad parameterisering finns i Guidelines for Using Forced Parameterization.
  • Manuellt skapade Query Store-tips är undantagna från rensning. Tipset och sökfrågan kommer inte att rensas från Query Store genom automatisk kvarhållning av insamlingspolicyn.
    • Frågor kan tas bort manuellt av användare, vilket också skulle ta bort den associerade Query Store-hinten.
    • Query Store-hints som automatiskt genereras av CE Feedback omfattas av rensning genom den automatiska kvarhållningen av inspelningspolicyn.
    • DOP-feedback och minnesbidragsfeedback formar frågebeteendet utan att använda Query Store-tips. När förfrågningar rensas genom automatisk bevarande av upptagningspolitik, rensas även DOP-feedback och minnesutdelningsfeedback.
    • Du kan manuellt skapa samma Query Store-hint som implementerades av CE feedback, och sedan skulle frågan med hinten inte längre påverkas av den automatiska rensningen enligt avbildningsprincipens kvarhållningspolicy.

Frågelagerindikatorer och tillgänglighetsgrupper

Frågearkivtips har ingen effekt på sekundära repliker, om inte Query Store är aktiverat för dessa repliker. För mer information, se Query Store för sekundära repliker.

  • Innan SQL Server 2022 (16.x) kan Query Store-hintar användas mot den primära repliken i en Always On-tilgänglighetsgrupp.
  • Från och med SQL Server 2022 (16.x), när Query Store för sekundära repliker är aktiverat, är Query Store-hints också replikmedvetna för sekundära repliker i tillgänglighetsgrupper.
  • Du kan lägga till ett Query Store-tips till en specifik replik eller replikuppsättning när du har Query Store för sekundära repliker aktiverat. I sys.sp_query_store_set_query_hintsanges detta av parametern @query_hint_scope som introducerades i SQL Server 2022 (16.x).
  • Hitta tillgängliga replikuppsättningar genom att fråga sys.query_store_replicas.
  • Hitta planer som tvingas på sekundära repliker med sys.query_store_plan_forcing_locations.

Metodtips för Query Store-tips

  • Slutför index- och statistikunderhållet innan du utvärderar frågor för potentiella nya Query Store-tips.
  • Testa programdatabasen på den senaste kompatibilitetsnivån innan du använder Query Store-tips.
    • Till exempel introducerades optimering av parameterkänslig plan (PSP) i SQL Server 2022 (16.x) (kompatibilitetsnivå 160), som använder flera aktiva planer per fråga för att hantera icke-enhetliga datadistributioner. Om din miljö inte kan använda den senaste kompatibilitetsnivån kan du använda Query Store-hints med RECOMPILE-hint på vilken som helst stödjande kompatibilitetsnivå.
  • Tips från Query Store åsidosätter beteendet för SQL Servers frågeplan. Vi rekommenderar att du endast använder Query Store-tips när det är nödvändigt för att åtgärda prestandarelaterade problem.
  • Vi rekommenderar att du omvärderar Query Store-anvisningar, instruktionsspecifika anvisningar, planguider och framtvingade planer för Query Store när datadistributioner ändras och under databasmigreringsprojekt. Ändringar i datadistributionen kan leda till att Query Store-indikationer genererar suboptimala exekveringsplaner.

Exempel

A. Demo av tips för Query Store

Följande genomgång av Query Store-tips i Azure SQL Database använder en importerad databas via en BACPAC-fil (.bacpac). Läs mer om hur du importerar en ny databas till en Azure SQL Database-server i Snabbstart: Importera en BACPAC-fil till en databas.

-- ************************************************************************ --
-- Query Store hints demo

-- Demo uses "PropertyMLS" database which can be imported from BACPAC here:
-- https://github.com/microsoft/sql-server-samples/tree/master/samples/features/query-store

-- Email QSHintsFeedback@microsoft.com for questions\feedback
-- ************************************************************************ --

/*
    Demo prep, connect to the PropertyMLS database
*/

ALTER DATABASE [PropertyMLS] SET QUERY_STORE CLEAR;
ALTER DATABASE CURRENT SET QUERY_STORE = ON;
ALTER DATABASE CURRENT SET QUERY_STORE  (QUERY_CAPTURE_MODE = ALL);
GO

-- Should be READ_WRITE
SELECT actual_state_desc
FROM sys.database_query_store_options;
GO

/*
    You can verify Query Store Hints in sys.query_store_query_hints.
    Checking if any already exist (should be none).
*/
SELECT	query_hint_id,
        query_id,
        query_hint_text,
        last_query_hint_failure_reason,
        last_query_hint_failure_reason_desc,
        query_hint_failure_count,
        source,
        source_desc
FROM sys.query_store_query_hints;
GO

/*
     The PropertySearchByAgent stored procedure has a parameter
     used to filter AgentId.  Looking at the statistics for AgentId,
     you will see that there is a big skew for AgentId 101.
*/
SELECT	hist.range_high_key AS [AgentId],
        hist.equal_rows
FROM sys.stats AS s
CROSS APPLY sys.dm_db_stats_histogram(s.[object_id], s.stats_id) AS hist
WHERE s.[name] = N'NCI_Property_AgentId';


-- Show actual query execution plan to see plan compiled.
-- Agent with many properties will have a scan with parallelism.
EXEC [dbo].[PropertySearchByAgent] 101;

-- Agents with few properties still re-use this plan (assuming no recent plan eviction).
EXEC [dbo].[PropertySearchByAgent] 4;


/*
    Now let's find the query_id associated with this query.
*/
SELECT query_sql_text, q.query_id
FROM sys.query_store_query_text qt
INNER JOIN sys.query_store_query q ON
    qt.query_text_id = q.query_text_id
WHERE query_sql_text like N'%ORDER BY ListingPrice DESC%' and query_sql_text not like N'%query_store%';
GO

/*
     We can set the hint associated with the query_id returned in the previous result set, as below.
     Note, we can designate one or more query hints
*/
EXEC sp_query_store_set_hints @query_id=5, @value = N'OPTION(RECOMPILE)';
GO

/*
    You can verify Query Store Hints in sys.query_store_query_hints
*/
SELECT	query_hint_id,
        query_id,
        query_hint_text,
        last_query_hint_failure_reason,
        last_query_hint_failure_reason_desc,
        query_hint_failure_count,
        source,
        source_desc
FROM sys.query_store_query_hints;
GO

-- Execute both at the same time and show actual query execution plan.
-- You should see two different plans, one for AgentId 101 and one for AgentId 4.
EXEC [dbo].[PropertySearchByAgent] 101;
EXEC [dbo].[PropertySearchByAgent] 4;
GO

SELECT	query_hint_id,
        query_id,
        query_hint_text,
        last_query_hint_failure_reason,
        last_query_hint_failure_reason_desc,
        query_hint_failure_count,
        source,
        source_desc
FROM sys.query_store_query_hints;
GO

/*
    We can remove the hint using sp_query_store_clear_query_hints
*/
EXEC sp_query_store_clear_hints @query_id = 10;
GO

/*
    That Query Store Hint is now removed
*/
SELECT	query_hint_id,
        query_id,
        query_hint_text,
        last_query_hint_failure_reason,
        last_query_hint_failure_reason_desc,
        query_hint_failure_count,
        source,
        source_desc
FROM sys.query_store_query_hints;
GO

-- Execute both at the same time and show actual query execution plan.
-- You should see one plan again.
EXEC [dbo].[PropertySearchByAgent] 101;
EXEC [dbo].[PropertySearchByAgent] 4;
GO

B. Identifiera en fråga i Query Store

Följande exempel frågar sys.query_store_query_text och sys.query_store_query för att returnera query_id för ett kört frågetextfragment.

I den här demonstrationen finns frågan som vi försöker finjustera i SalesLT exempeldatabas:

SELECT * FROM SalesLT.Address as A 
INNER JOIN SalesLT.CustomerAddress as CA
on A.AddressID = CA.AddressID
WHERE PostalCode = '98052' ORDER BY A.ModifiedDate DESC;

Query Store återspeglar inte omedelbart frågedata till sina systemvyer.

Identifiera frågan i frågearkivets systemkatalogvyer:

SELECT q.query_id, qt.query_sql_text
FROM sys.query_store_query_text qt 
INNER JOIN sys.query_store_query q ON 
    qt.query_text_id = q.query_text_id 
WHERE query_sql_text like N'%PostalCode =%'  
  AND query_sql_text not like N'%query_store%';
GO

I följande exempel identifierades det tidigare frågeexemplet i SalesLT-databasen som query_id 39.

När du har identifierat det använder du tipset för att framtvinga en maximal minnesanvändningsstorlek i procent av den konfigurerade minnesgränsen för query_id:

EXEC sys.sp_query_store_set_hints @query_id= 39, @query_hints = N'OPTION(MAX_GRANT_PERCENT=10)';

Du kan också använda frågetips med följande syntax, till exempel alternativet att framtvinga äldre kardinalitetsestimator:

EXEC sys.sp_query_store_set_hints @query_id= 39, @query_hints = N'OPTION(USE HINT(''FORCE_LEGACY_CARDINALITY_ESTIMATION''))';

Du kan använda flera frågetips med en kommaavgränsad lista:

EXEC sys.sp_query_store_set_hints @query_id= 39, @query_hints = N'OPTION(RECOMPILE, MAXDOP 1, USE HINT(''QUERY_OPTIMIZER_COMPATIBILITY_LEVEL_110''))';

Granska Query Store-tipset för query_id 39:

SELECT query_hint_id, query_id, query_hint_text, last_query_hint_failure_reason, last_query_hint_failure_reason_desc, query_hint_failure_count, source, source_desc 
FROM sys.query_store_query_hints 
WHERE query_id = 39;

Ta slutligen bort tipset från query_id 39 med hjälp av sp_query_store_clear_hints.

EXEC sys.sp_query_store_clear_hints @query_id = 39;