Övervaka prestanda med frågearkiv
GÄLLER FÖR: Azure Database for PostgreSQL – flexibel server
Query Store är en funktion i Azure Database for PostgreSQL – flexibel server 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 frågor lagras i en databas med namnet azure_sys
i azure database for PostgreSQL– flexibel 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
top
ellerall
, 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_sys
databasen.
Aktivera väntesampling för frågearkiv
- Sök efter parametern
pgms_wait_sampling.query_capture_mode
. - Ange värdet till
all
och Spara.
Information i frågearkivet
Frågearkiv består av två butiker:
- Ett körningsstatistiklager för att bevara information om frågekörningsstatistik.
- 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 körningstiden för en fråga över tidsfönster för att se 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örningsstatistiken i statistikarkivet för körning ö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 | Åtgärd |
---|---|
Långa väntetider för 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 frågearkivet. Om de matchar frågorna med höga I/O-väntetider kan du överväga att aktivera funktionen för automatisk indexjustering 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. |
Väntetider med högt minne | 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 frigörs 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 | Standard | Intervall |
---|---|---|---|
pg_qs.interval_length_minutes (*) |
Avbildningsintervall i minuter för frågearkivet. Definierar frekvensen för datapersistence. | 15 |
1 - 30 |
pg_qs.is_enabled_fs |
Endast internt bruk: Den här parametern används som en funktions åsidosättningsväxel. Om det visas som av inaktiveras frågearkivet, trots värdet som angetts för pg_qs.query_capture_mode . |
on |
on , off |
pg_qs.max_plan_size |
Maximalt antal byte som sparats från frågeplanens text efter frågearkiv. 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 avbildas. | capture_parameterless_only |
capture_parameterless_only , capture_first_sample |
pg_qs.query_capture_mode |
Instruktioner att spåra. | none |
none , , top all |
pg_qs.retention_period_in_days |
Fönstret Kvarhållningsperiod i dagar för frågearkivet. Äldre data tas bort automatiskt. | 7 |
1 - 30 |
pg_qs.store_query_plans |
Om frågeplaner ska sparas i frågearkivet. | off |
on , off |
pg_qs.track_utility |
Om frågearkivet måste spåra verktygskommandon. | on |
on , off |
(*) Statisk serverparameter som kräver en omstart av servern för att en ändring av dess värde ska börja gälla.
Följande alternativ gäller specifikt för väntestatistik:
Parameter | Beskrivning | Standard | Intervall |
---|---|---|---|
pgms_wait_sampling.history_period |
Frekvens, i millisekunder, där väntehändelser samplas. | 100 |
1 - 600000 |
pgms_wait_sampling.is_enabled_fs |
Endast internt bruk: Den här parametern används som en funktions åsidosättningsväxel. Om det visas som off inaktiveras väntesampling trots värdet som angetts för pgms_wait_sampling.query_capture_mode . |
on |
on , off |
pgms_wait_sampling.query_capture_mode |
Vilka instruktioner pgms_wait_sampling tillägget måste spåra. |
none |
none , all |
Kommentar
pg_qs.query_capture_mode
ersätter pgms_wait_sampling.query_capture_mode
. Om pg_qs.query_capture_mode
är none
har 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.
Vyer
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 | Typ | Referenser | Beskrivning |
---|---|---|---|
runtime_stats_entry_id |
bigint | ID från tabellen runtime_stats_entries. | |
user_id |
Oid | pg_authid.oid | OID för 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 för en representativ instruktion. 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 här maximala värdet trunkeras den till de första pg_qs.max_query_text_length tecknen. |
|
plan_id |
bigint | ID för planen som motsvarar den här frågan. | |
start_time |
timestamp | 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 där posten spelades in. |
|
end_time |
timestamp | 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 serverdelsprocessen som driver körningen av frågan, plus lika många andra enheter för varje backend worker-process som startas för att samarbeta och köra de parallella grenarna i körningsträdet. | |
total_time |
dubbel precision | Total körningstid för frågor i millisekunder. | |
min_time |
dubbel precision | Minsta körningstid för frågor i millisekunder. | |
max_time |
dubbel precision | Maximal körningstid för frågor i millisekunder. | |
mean_time |
dubbel precision | Genomsnittlig körningstid för frågor i millisekunder. | |
stddev_time |
dubbel precision | Standardavvikelse för frågekörningstiden 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 serverdelsprocessen som driver körningen av frågan, plus summan av alla rader som varje serverdelsarbetsprocess, som startas för att samarbeta och köra de parallella grenarna i körningsträdet, återgår till serverdelsprocessen som driver körningen av frågan. | |
shared_blks_hit |
bigint | Totalt antal delade blockcacheträffar av -instruktionen. | |
shared_blks_read |
bigint | Totalt antal delade block som lästs av -instruktionen. | |
shared_blks_dirtied |
bigint | Totalt antal delade block som smutsas in av -instruktionen. | |
shared_blks_written |
bigint | Totalt antal delade block som skrivits av -instruktionen. | |
local_blks_hit |
bigint | Totalt antal lokala blockcacheträ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 smutsas in av -instruktionen. | |
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 -instruktionen. | |
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 |
boolean | 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 |
text | 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 |
text | Värdet för search_path anges när frågan hämtades. | |
query_parameters |
text | 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örning. |
|
parameters_capture_status |
text | 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 har avbildats), disabled (frågan parametriserades men parametrarna har inte avbildats eftersom var inställt capture_parameterless_only på pg_qs.parameters_capture_mode ), too_long_to_capture (frågan parametriserades, men parametrarna hämtades inte eftersom längden på den resulterande JSON som skulle visas i kolumnen i den query_parameters här vyn ansågs vara överdrivet lång för att frågearkivet skulle bevaras). too_many_to_capture (frågan parametriserades, men parametrarna fångades inte eftersom det totala antalet parametrar ansågs vara överdrivet för att frågearkivet skulle sparas), serialization_failed (frågan parametriserades, men minst ett av de värden som skickades som en parameter kunde inte serialiseras till text). |
query_store.query_texts_view
Den här vyn returnerar frågetextdata i Query Store. Det finns en rad för varje distinkt query_sql_text.
Namn | Typ | Beskrivning |
---|---|---|
query_text_id |
bigint | ID för tabellen query_texts |
query_sql_text |
varchar(10000) | Text för en representativ instruktion. 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 | Typ | Referenser | Beskrivning |
---|---|---|---|
start_time |
timestamp | 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 där posten spelades in. |
|
end_time |
timestamp | Sluttid som motsvarar tidsfönstret för den här posten. | |
user_id |
Oid | pg_authid.oid | Objektidentifierare för användare som kö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 |
text | Den typ av händelse som serverdelen väntar på. | |
event |
text | Namnet på väntehändelsen om serverdelen för närvarande väntar. | |
calls |
integer | Antal gånger samma händelse registrerades. |
Kommentar
En lista över möjliga värden i kolumnerna event_type
query_store.pgms_wait_sampling_view
och event
i vyn finns i den officiella dokumentationen för pg_stat_activity och letar efter informationen som refererar till kolumner med samma namn.
query_store.query_plans_view
Den här vyn returnerar den frågeplan som användes för att köra 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 | Typ | 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 given costs=false, buffers=false och format=text. Identiska utdata som den som skapas av EXPLAIN. |
Funktioner
query_store.qs_reset
Den här funktionen tar bort all statistik som hittills samlats in av frågearkivet. 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 tar bort all statistik som samlats in i minnet efter frågelager (det vill: data i minnet som ännu inte har rensats till disktabellerna som stöder beständighet av insamlade data för frågelager). Endast medlemmar i serveradministratörsrollen (azure_pg_admin
) kan köra den här funktionen.
Skrivskyddat läge
När en instans av Azure Database for PostgreSQL – flexibel server ä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 nårs, 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 de skrivskyddade replikerna registrerar inte frågearkivet de frågor som körs på skrivskyddade repliker, eftersom de fungerar i skrivskyddat läge förrän du befordrar dem till primära.