Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Query Store är en funktion i en flexibel Azure Database for PostgreSQL-serverinstans som ger ett sätt att spåra frågeprestanda över tid. Query Store förenklar felsökningen av prestandaproblem genom att hjälpa dig att snabbt hitta de längsta och mest resursintensiva frågorna. Frågearkivet samlar automatiskt in en historik över frågor och körningsstatistik och behåller dem för din granskning. Den delar upp data efter tid så att du kan se tidsmässiga användningsmönster. Data för alla användare, databaser och sökningar lagras i en databas med namnet azure_sys i Azure Database for PostgreSQL flexibil serverinstans.
Aktivera frågearkiv
Query Store är tillgängligt att använda utan extra avgifter. Det är en opt-in-funktion, så den är inte aktiverad som standard på en server. Frågearkiv kan aktiveras eller inaktiveras globalt för alla databaser på en viss server och kan inte aktiveras eller inaktiveras per databas.
Viktigt!
Aktivera inte frågearkivet på prisnivån Burstable eftersom det skulle orsaka prestandapåverkan.
Aktivera frågearkiv i Azure Portal
- Logga in på Azure Portal och välj din flexibla Serverinstans för Azure Database for PostgreSQL.
- Välj Serverparametrar i avsnittet Inställningar på menyn.
- Sök efter parametern
pg_qs.query_capture_mode. - Ange värdet till
topellerall, beroende på om du vill spåra frågor på den översta nivån eller även kapslade frågor (de som körs i en funktion eller procedur) och välj Spara. Tillåt upp till 20 minuter för den första databatchen att sparas iazure_sysdatabasen.
Aktivera väntesampling för frågelagring
- Sök efter parametern
pgms_wait_sampling.query_capture_mode. - Ange värdet till
alloch Spara.
Information i frågearkivet
Frågelager består av två lager:
- Ett statistiklager för körningstid för att bevara information om utföranden av frågestatistik.
- Ett väntestatistikarkiv för att spara information om väntestatistik.
Vanliga scenarier för att använda frågearkivet är:
- Fastställa hur många gånger en fråga kördes under en viss tidsperiod.
- Jämföra den genomsnittliga exekveringstiden för en fråga över olika tidsintervall för att observera stora variationer.
- Identifiera de frågor som har körts längst under de senaste timmarna.
- Identifiera de främsta N-frågorna som väntar på resurser.
- Förstå typen av väntetider för en viss fråga.
För att minimera utrymmesanvändningen aggregeras körstatistiken i körstatistikarkivet över ett fast, konfigurerbart tidsfönster. Informationen i dessa butiker kan efterfrågas med hjälp av vyer.
Åtkomst till information om frågearkiv
Frågelagringsdata lagras i azure_sys databasen på din flexibla Azure Database for PostgreSQL-serverinstans.
Följande fråga returnerar information om frågor som har registrerats i frågearkivet:
SELECT * FROM query_store.qs_view;
Och den här frågan returnerar information om väntande statistik:
SELECT * FROM query_store.pgms_wait_sampling_view;
Hitta väntefrågor
Väntehändelsetyper kombinerar olika väntehändelser i bucketar efter likhet. Frågearkivet innehåller typen av väntehändelse, ett specifikt namn på väntehändelsen och frågan i fråga. Om du kan korrelera den här vänteinformationen med frågekörningsstatistiken kan du få en djupare förståelse för vad som bidrar till frågeprestandaegenskaper.
Här följer några exempel på hur du kan få mer insikter om din arbetsbelastning med hjälp av väntestatistiken i frågearkivet:
| Observation | Action |
|---|---|
| Hög väntetid vid lås | Kontrollera frågetexterna för de berörda frågorna och identifiera målentiteterna. Leta i frågearkivet efter andra frågor som körs ofta och/eller har hög varaktighet och ändrar samma entitet. När du har identifierat dessa frågor kan du överväga att ändra programlogik för att förbättra samtidigheten eller använda en mindre restriktiv isoleringsnivå. |
| I/O-väntetider med hög buffert | Hitta frågorna med ett stort antal fysiska läsningar i Query Store. Om de matchar frågorna med höga I/O-väntetider kan du överväga att aktivera funktionen för autonom justering för att se om den kan rekommendera att du skapar några index som kan minska antalet fysiska läsningar för dessa frågor. |
| Höga minnesväntetider | Hitta de vanligaste minneskrävande frågorna i frågearkivet. Dessa frågor fördröjer förmodligen ytterligare förlopp för de berörda frågorna. |
Konfigurationsalternativ
När frågearkivet är aktiverat sparar det data i aggregeringsfönster med längd som bestäms av serverparametern pg_qs.interval_length_minutes (standardvärdet är 15 minuter). För varje fönster lagras upp till 500 distinkta frågor per fönster. Attribut som särskiljer unikheten för varje fråga är user_id (identifierare för användaren som kör frågan), db_id (identifierare för databasen i vars kontext frågan körs) och query_id (ett heltalsvärde som unikt identifierar frågan som körs). Om antalet distinkta frågor når 500 under det konfigurerade intervallet frigörs 5 % av de som registreras för att göra plats för fler. De som avallokeras först är de som kördes minst antal gånger.
Följande alternativ är tillgängliga för att konfigurera Query Store-parametrar:
| Parameter | Beskrivning | Standardinställning | Intervall |
|---|---|---|---|
pg_qs.interval_length_minutes |
Insamlingsintervall i minuter för frågearkivet. Definierar frekvensen för datapersistence. | 15 |
1 - 30 |
pg_qs.max_captured_queries |
Maximalt antal frågor som sparas av frågearkivet från alla frågor som registrerats under varje insamlingsintervall. | 500 |
100 - 500 |
pg_qs.max_plan_size |
Maximalt antal byte som sparats från frågeplanens text i frågelagring; längre planer trunkeras. | 7500 |
100 - 10000 |
pg_qs.max_query_text_length |
Maximal frågelängd som kan sparas. längre frågor trunkeras. | 6000 |
100 - 10000 |
pg_qs.parameters_capture_mode |
Om och när frågepositionsparametrar ska fångas in. | capture_parameterless_only |
capture_parameterless_only, capture_first_sample |
pg_qs.query_capture_mode |
Uttalanden att spåra. | none |
none, topall |
pg_qs.retention_period_in_days |
Kvarhållningsperiod i dagar för frågelagret. Äldre data tas bort automatiskt. | 7 |
1 - 30 |
pg_qs.store_query_plans |
Om frågeplaner ska sparas i frågelagret. | off |
on, off |
pg_qs.track_utility |
Om Query Store måste spåra kommandon för hjälpverktyg. | on |
on, off |
Anmärkning
Om du ändrar värdet för parametern fortsätter texten för pg_qs.max_query_text_length alla frågor som hämtades innan du gör ändringen att använda samma query_id och sql_query_text. Det kan ge intryck av att det nya värdet inte börjar gälla, men för frågor som inte har registrerats i frågearkivet tidigare ser du att frågetexten använder den nyligen konfigurerade maximala längden. Detta är avsiktligt och förklaras i Vyer och funktioner. Om du kör query_store.qs_reset tas all information som registrerats av frågearkivet bort fram till nu, inklusive texten som har samlats in för varje fråge-ID, och om någon av dessa frågor körs igen tillämpas den nyligen konfigurerade maximala längden på texten som samlas in.
Följande alternativ gäller specifikt för väntestatistik:
| Parameter | Beskrivning | Standardinställning | Intervall |
|---|---|---|---|
pgms_wait_sampling.history_period |
Frekvens, i millisekunder, där väntehändelser samplas. | 100 |
1 - 600000 |
pgms_wait_sampling.query_capture_mode |
Vilka uttalanden tillägget pgms_wait_sampling måste spåra. |
none |
none, all |
Anmärkning
pg_qs.query_capture_mode ersätter pgms_wait_sampling.query_capture_mode. Om pg_qs.query_capture_mode är nonehar inställningen pgms_wait_sampling.query_capture_mode ingen effekt.
Använd Azure Portal för att hämta eller ange ett annat värde för en parameter.
Vyer och funktioner
Du kan köra frågor mot den information som registreras av frågearkivet och/eller ta bort den med hjälp av vissa vyer och funktioner som är tillgängliga i query_store-schemat för azure_sys-databasen. Vem som helst i den offentliga PostgreSQL-rollen kan använda dessa vyer för att se data i frågearkivet. Dessa vyer är endast tillgängliga i azure_sys-databasen.
Frågor normaliseras genom att titta på deras struktur och ignorera allt som inte är semantiskt betydelsefullt, till exempel literaler, konstanter, alias eller skillnader i hölje.
Om två frågor är semantiskt identiska, även om de använder olika alias för samma refererade kolumner och tabeller, identifieras de med samma query_id. Om två frågor bara skiljer sig åt i de literalvärden som används i dem identifieras de också med samma query_id. För frågor som identifieras med samma query_id är deras sql_query_text den fråga som kördes först sedan frågearkivet startade inspelningsaktiviteten, eller sedan den senaste gången de sparade data togs bort eftersom funktionen query_store.qs_reset kördes.
Så här fungerar frågenormalisering
Här följer några exempel för att försöka illustrera hur den här normaliseringen fungerar:
Anta att du skapar en tabell med följande instruktion:
create table tableOne (columnOne int, columnTwo int);
Du aktiverar Query Store-datainsamling och en eller flera användare kör följande frågor i exakt den här ordningen:
select * from tableOne;
select columnOne, columnTwo from tableOne;
select columnOne as c1, columnTwo as c2 from tableOne as t1;
select columnOne as "column one", columnTwo as "column two" from tableOne as "table one";
Alla tidigare frågor delar samma query_id. Och texten som Query Store behåller är den för den första frågan som körs efter aktivering av datainsamling. Därför skulle det vara select * from tableOne;.
Följande uppsättning frågor, när de har normaliserats, matchar inte den tidigare uppsättningen frågor eftersom WHERE-satsen gör dem semantiskt olika:
select columnOne as c1, columnTwo as c2 from tableOne as t1 where columnOne = 1 and columnTwo = 1;
select * from tableOne where columnOne = -3 and columnTwo = -3;
select columnOne, columnTwo from tableOne where columnOne = '5' and columnTwo = '5';
select columnOne as "column one", columnTwo as "column two" from tableOne as "table one" where columnOne = 7 and columnTwo = 7;
Alla frågor i den senaste uppsättningen delar dock samma query_id och den text som används för att identifiera dem alla är den första frågan i batchen select columnOne as c1, columnTwo as c2 from tableOne as t1 where columnOne = 1 and columnTwo = 1;.
Slutligen hittar du nedan några frågor som inte matchar query_id av dem i föregående batch och orsaken till att de inte gör det:
Fråga:
select columnTwo as c2, columnOne as c1 from tableOne as t1 where columnOne = 1 and columnTwo = 1;
Orsak till att den inte matchar: Listan över kolumner refererar till samma två kolumner (columnOne och ColumnTwo), men ordningen som de hänvisas till är omvänd, från columnOne, ColumnTwo i föregående batch till ColumnTwo, columnOne i den här frågan.
Fråga:
select * from tableOne where columnTwo = 25 and columnOne = 25;
Orsak till att inte matcha: Ordningen där de uttryck som utvärderas i WHERE-satsen refereras återförs från columnOne = ? and ColumnTwo = ? i föregående batch till ColumnTwo = ? and columnOne = ? i den här frågan.
Fråga:
select abs(columnOne), columnTwo from tableOne where columnOne = 12 and columnTwo = 21;
Orsak till att inte matcha: Det första uttrycket i kolumnlistan är inte columnOne längre, utan funktionen abs utvärderas över columnOne (abs(columnOne)), vilket inte är semantiskt likvärdigt.
Fråga:
select columnOne as "column one", columnTwo as "column two" from tableOne as "table one" where columnOne = ceiling(16) and columnTwo = 16;
Orsak till att inte matcha: Det första uttrycket i WHERE-satsen utvärderar inte likheten columnOne med en literal längre, utan med resultatet av funktionen ceiling utvärderad över en literal, vilket inte är semantiskt likvärdigt.
Views
query_store.qs_view
Den här vyn returnerar alla data som sparas i stödtabellerna i frågearkivet. Data som fortfarande registrerar minnesinternt för det aktuella aktiva tidsfönstret visas inte förrän tidsfönstret har upphört och dess minnesinterna data samlas in och sparas i tabeller som lagras på disken. Den här vyn returnerar en annan rad för varje distinkt databas (db_id), användare (user_id) och fråga (query_id).
| Namn | Type | Referenser | Beskrivning |
|---|---|---|---|
runtime_stats_entry_id |
Bigint | ID från tabellen runtime_stats_entries. | |
user_id |
oid | pg_authid.oid | OID av användare som körde instruktionen. |
db_id |
oid | pg_database.oid | OID för databasen där -instruktionen kördes. |
query_id |
Bigint | Intern hash-kod som beräknas från instruktionens parsningsträd. | |
query_sql_text |
varchar(10000) | Text av ett representativt uttalande. Olika frågor med samma struktur grupperas tillsammans. den här texten är texten för den första av frågorna i klustret. Standardvärdet för den maximala frågetextlängden är 6 000 och kan ändras med frågelagringsparametern pg_qs.max_query_text_length. Om texten i frågan överskrider det maximala värdet trunkeras den till de första pg_qs.max_query_text_length byteen. |
|
plan_id |
Bigint | ID för planen som motsvarar den här frågan. | |
start_time |
tidsstämpel | Frågor aggregeras efter tidsfönster. Serverparametern pg_qs.interval_length_minutes definierar tidsintervallet för dessa fönster (standardvärdet är 15 minuter). Den här kolumnen motsvarar starttiden för fönstret i vilket uppgiften registrerades. |
|
end_time |
tidsstämpel | Sluttid som motsvarar tidsfönstret för den här posten. | |
calls |
Bigint | Antal gånger som frågan kördes i det här tidsfönstret. Observera att för parallella frågor motsvarar antalet anrop för varje körning 1 för backend-processen som driver frågans körning, plus lika många andra enheter för varje backend-arbetsprocess som startas för att samarbeta och utföra de parallella grenarna i exekveringsträdet. | |
total_time |
dubbel precision | Total frågeexekveringstid i millisekunder. | |
min_time |
dubbel precision | Minsta fråga körningstid i millisekunder. | |
max_time |
dubbel precision | Maximal exekveringstid för frågor i millisekunder. | |
mean_time |
dubbel precision | Genomsnittlig exekveringstid för sökfrågor i millisekunder. | |
stddev_time |
dubbel precision | Standardavvikelse för exekveringstiden för frågan i millisekunder. | |
rows |
Bigint | Totalt antal rader som hämtats eller påverkats av instruktionen. Observera att för parallella frågor motsvarar antalet rader för varje körning antalet rader som returneras till klienten av backend-processen som driver frågekörningen, plus summan av alla rader som varje backend-arbetsprocess, startad för att samverka i körningen av de parallella grenarna i exekveringsträdet, skickar tillbaka till backend-processen som driver frågekörningen. | |
shared_blks_hit |
Bigint | Totalt antal delade blockcacheträffar av -instruktionen. | |
shared_blks_read |
Bigint | Totalt antal delade block som lästs av uttrycket. | |
shared_blks_dirtied |
Bigint | Antalet delade block som förändras av uttrycket. | |
shared_blks_written |
Bigint | Totalt antal gemensamma block som skrivits av instruktionen. | |
local_blks_hit |
Bigint | Det totala antalet lokala block-cacheträffar av instruktionen. | |
local_blks_read |
Bigint | Totalt antal lokala block som lästs av instruktionen. | |
local_blks_dirtied |
Bigint | Totalt antal lokala block som smutsats ner av uttalandet. | |
local_blks_written |
Bigint | Totalt antal lokala block som skrivits av instruktionen. | |
temp_blks_read |
Bigint | Totalt antal temporära block som lästs av påståendet. | |
temp_blks_written |
Bigint | Totalt antal temporära block som skrivits av instruktionen. | |
blk_read_time |
dubbel precision | Total tid som instruktionen spenderade på att läsa block, i millisekunder (om track_io_timing är aktiverad, annars noll). | |
blk_write_time |
dubbel precision | Total tid som instruktionen spenderade på att skriva block, i millisekunder (om track_io_timing är aktiverad, annars noll). | |
is_system_query |
booleskt | Avgör om rollen med user_id = 10 (azuresu) körde frågan. Den användaren har superanvändarbehörighet och används för att utföra kontrollplansåtgärder. Eftersom den här tjänsten är en hanterad PaaS-tjänst är endast Microsoft en del av den superanvändarrollen. | |
query_type |
texten | Typ av åtgärd som representeras av frågan. Möjliga värden är unknown, select, update, insert, delete, merge, utility, , nothing, undefined. |
|
search_path |
texten | Värdet för search_path anges när frågan hämtades. | |
query_parameters |
texten | Textrepresentation av ett JSON-objekt med de värden som skickas till positionsparametrarna för en parametriserad fråga. Den här kolumnen fyller bara i värdet i två fall: 1) för frågor som inte ärparameteriserade. 2) För parametriserade frågor, när pg_qs.parameters_capture_mode är inställt på capture_first_sample, och om frågearkivet kan hämta värdena för parametrarna för frågan vid körningstid. |
|
parameters_capture_status |
texten | Typ av åtgärd som representeras av frågan. Möjliga värden är succeeded (antingen parameteriserades inte frågan eller så var det en parametriserad fråga och värden fångades), disabled (frågan parametriserades men parametrarna fångades inte eftersom pg_qs.parameters_capture_mode var inställt på capture_parameterless_only), too_long_to_capture (frågan parametriserades, men parametrarna fångades inte eftersom längden på den resulterande JSON som skulle visas i query_parameters-kolumnen i den här vyn ansågs överdrivet lång för att frågelagringen skulle bevara den), too_many_to_capture (frågan parametriserades, men parametrarna fångades inte eftersom det totala antalet parametrar ansågs överdrivet för att frågelagringen skulle spara dem), serialization_failed (frågan parametriserades, men minst ett av de värden som skickades som en parameter kunde inte serialiseras till text). |
frågebutik.förfrågnings_text_vy
Den här vyn returnerar frågetextdata i Query Store. Det finns en rad för varje unik query_sql_text.
| Namn | Type | Beskrivning |
|---|---|---|
query_text_id |
Bigint | ID för tabellen query_texts |
query_sql_text |
varchar(10000) | Text av ett representativt uttalande. Olika frågor med samma struktur grupperas tillsammans. den här texten är texten för den första av frågorna i klustret. |
query_type |
smallint | Typ av åtgärd som representeras av frågan. I versionen av PostgreSQL <= 14 är 0 möjliga värden (okända), 1 (välj), 2 (uppdatera), 3 (infoga), 4 (ta bort), 5 (verktyg) 6 (ingenting). I versionen av PostgreSQL >= 15 är 0 möjliga värden (okända), 1 (välj), 2 (uppdatera), 3 (infoga), 4 (ta bort), 5 (sammanfoga), 6 (verktyg), 7 (ingenting). |
query_store.pgms_wait_sampling_view
Den här vyn returnerar väntehändelser i Query Store. Den här vyn returnerar en annan rad för varje distinkt databas (db_id), användare (user_id), fråga (query_id) och händelse (händelse).
| Namn | Type | Referenser | Beskrivning |
|---|---|---|---|
start_time |
tidsstämpel | Frågor aggregeras efter tidsfönster. Serverparametern pg_qs.interval_length_minutes definierar tidsintervallet för dessa fönster (standardvärdet är 15 minuter). Den här kolumnen motsvarar starttiden för fönstret i vilket uppgiften registrerades. |
|
end_time |
tidsstämpel | Sluttid som motsvarar tidsfönstret för den här posten. | |
user_id |
oid | pg_authid.oid | Objektidentifierare för användare som utförde instruktionen. |
db_id |
oid | pg_database.oid | Objektidentifierare för databasen där instruktionen kördes. |
query_id |
Bigint | Intern hash-kod som beräknas från instruktionens parsningsträd. | |
event_type |
texten | Den typ av händelse som serverdelen väntar på. | |
event |
texten | Namnet på väntehändelsen om serverdelen för närvarande väntar. | |
calls |
integer | Antal gånger samma händelse registrerades. |
Anmärkning
För en lista över möjliga värden i kolumnerna event_type och event i vyn query_store.pgms_wait_sampling_view, hänvisa till den officiella dokumentationen för pg_stat_activity och leta efter information som refererar till kolumner med samma namn.
query_store.query_plans_view
Den här vyn returnerar frågeplanen som användes för att exekvera en fråga. Det finns en rad per varje distinkt databas-ID och fråge-ID. Frågearkivet registrerar endast frågeplaner för frågor som inte används.
| Namn | Type | Referenser | Beskrivning |
|---|---|---|---|
plan_id |
Bigint | Hash-värdet från den normaliserade frågeplanen som skapats av EXPLAIN. Den är i normaliserad form eftersom den exkluderar de uppskattade kostnaderna för plannoder och användningen av buffertar. | |
db_id |
oid | pg_database.oid | OID för databasen där -instruktionen kördes. |
query_id |
Bigint | Intern hash-kod som beräknas från instruktionens parsningsträd. | |
plan_text |
varchar(10000) | Körningsplan för instruktionen givet costs=false, buffers=false och format=text. Identiska utdata som den som skapas av EXPLAIN. |
Functions
query_store.qs_reset
Den här funktionen tar bort all statistik som hittills samlats in av Query Store. Den tar bort statistiken för redan stängda tidsfönster, som redan finns kvar i disktabeller. Den tar också bort statistiken för det aktuella tidsfönstret, som bara finns i minnet. Endast medlemmar i serveradministratörsrollen (azure_pg_admin) kan köra den här funktionen.
query_store.staging_data_reset
Den här funktionen raderar all statistik som samlats in i minnet av frågelagring (det vill säga, data i minnet som ännu inte har skrivits till disktabellerna som stöder beständighet av insamlade data för frågelagring). Endast medlemmar i serveradministratörsrollen (azure_pg_admin) kan köra den här funktionen.
Skrivskyddat läge
När en flexibel Azure Database for PostgreSQL-serverinstans är i skrivskyddat läge, till exempel när parametern default_transaction_read_only är inställd på on, eller om skrivskyddat läge aktiveras automatiskt på grund av att lagringskapaciteten har nåtts, samlar frågearkivet inte in några data.
Om du aktiverar frågearkivet på en server som har läsrepliker aktiveras inte automatiskt frågearkiv på någon av de lästa replikerna. Även om du aktiverar det på någon av läsreplikerna, registrerar inte frågearkivet de frågor som körs på läsrepliker, eftersom de fungerar i läsläge tills du uppgraderar dem till primära.