sql >> Database teknologi >  >> RDS >> Sqlserver

SQL Server Query Store

Benjamin Nevarez er en uafhængig konsulent baseret i Los Angeles, Californien, som har specialiseret sig i tuning og optimering af SQL Server-forespørgsler. Han er forfatter til "SQL Server 2014 Query Tuning &Optimization" og "Inside the SQL Server Query Optimizer" og medforfatter til "SQL Server 2012 Internals". Med mere end 20 års erfaring i relationelle databaser har Benjamin også været foredragsholder ved mange SQL Server-konferencer, herunder PASS Summit, SQL Server Connections og SQLBits. Benjamins blog kan findes på http://www.benjaminnevarez.com, og han kan også nås via e-mail på admin på benjaminnevarez dot com og på twitter på @BenjaminNevarez.

Har du nogensinde fundet en planregression efter en SQL Server-opgradering og ønskede at vide, hvad den tidligere eksekveringsplan var? Har du nogensinde haft et problem med forespørgselsydeevne på grund af det faktum, at en forespørgsel uventet fik en ny eksekveringsplan? Ved det sidste PASS Summit afslørede Conor Cunningham en ny SQL Server-funktion, som kan være nyttig til at løse ydeevneproblemer relateret til disse og andre ændringer i eksekveringsplaner.

Denne funktion, kaldet Query Store, kan hjælpe dig med ydeevneproblemer i forbindelse med planændringer og vil snart være tilgængelig på SQL Azure og senere på den næste version af SQL Server. Selvom det forventes at være tilgængeligt på Enterprise Edition af SQL Server, vides det endnu ikke, om det vil være tilgængeligt på Standard eller andre udgaver. For at forstå fordelene ved Query Store, lad mig tale kort om forespørgselsfejlfindingsprocessen.

Hvorfor er en forespørgsel langsom?

Når du har opdaget, at et ydeevneproblem skyldes, at en forespørgsel er langsom, er næste skridt at finde ud af hvorfor. Det er klart, at ikke alle problemer er relateret til planændringer. Der kan være flere årsager til, at en forespørgsel, der har fungeret godt, pludselig er langsom. Nogle gange kan dette være relateret til blokering eller et problem med andre systemressourcer. Noget andet kan have ændret sig, men udfordringen kan være at finde ud af hvad. Mange gange har vi ikke en baseline om systemressourceforbrug, forespørgselsudførelsesstatistikker eller ydeevnehistorik. Og normalt aner vi ikke, hvad den gamle plan var. Det kan være tilfældet, at nogle ændringer, for eksempel data, skema eller forespørgselsparametre, fik forespørgselsprocessoren til at lave en ny plan.

Planlæg ændringer

Ved sessionen brugte Conor Picasso Database Query Optimizer Visualizer-værktøjet, selvom han ikke nævnte det ved navn, til at vise, hvorfor planerne i den samme forespørgsel ændrede sig, og forklarede det faktum, at forskellige planer kunne vælges til den samme forespørgsel baseret på selektiviteten af ​​deres prædikater. Han nævnte endda, at forespørgselsoptimeringsteamet bruger dette værktøj, som er udviklet af Indian Institute of Science. Et eksempel på visualiseringen (klik for at forstørre):

Picasso Database Query Optimizer Visualizer

Hver farve i diagrammet er en anden plan, og hver plan er valgt baseret på prædikaternes selektivitet. En vigtig kendsgerning er, når en grænse krydses i grafen, og en anden plan vælges, de fleste gange bør omkostningerne og ydeevnen for begge planer være ens, da selektiviteten eller det anslåede antal rækker kun ændrede sig en smule. Dette kan for eksempel ske, når en ny række tilføjes til en tabel, som kvalificerer til det brugte prædikat. Men i nogle tilfælde, for det meste på grund af begrænsninger i omkostningsmodellen for forespørgselsoptimering, hvor den ikke er i stand til at modellere noget korrekt, kan den nye plan have en stor ydeevneforskel i forhold til den forrige, hvilket skaber et problem for din applikation. I øvrigt er planerne vist på diagrammet den endelige plan valgt af forespørgselsoptimeringsværktøjet, forveksle dette ikke med de mange alternativer, som optimereren skal overveje for kun at vælge én.

En vigtig kendsgerning, efter min mening, som Conor ikke dækkede direkte, var ændringen af ​​planer på grund af regressioner efter ændringer på kumulative opdateringer (CU'er), service packs eller versionsopgraderinger. En stor bekymring, der kommer til at tænke på med ændringer i forespørgselsoptimeringsværktøjet, er planregression. Frygten for planregression er blevet betragtet som den største hindring for forbedringer af forespørgselsoptimering. Regressioner er problemer, der introduceres, efter at en rettelse er blevet anvendt på forespørgselsoptimeringsværktøjet, og nogle gange omtales som det klassiske "to eller flere forkerte gør en ret." Dette kan ske, når f.eks. to dårlige estimeringer, den ene overvurderer en værdi og den anden undervurderer den, ophæver hinanden, hvilket heldigvis giver et godt estimat. Korrigering af kun én af disse værdier kan nu føre til et dårligt estimat, som kan have en negativ indvirkning på valget af planvalg og forårsage en regression.

Hvad gør Query Store?

Conor nævnte, at Query Store udfører og kan hjælpe med følgende:

  1. Gem historikken for forespørgselsplaner i systemet;
  2. Fang ydeevnen af ​​hver forespørgselsplan over tid;
  3. Identificer forespørgsler, der er "blevet langsommere for nylig";
  4. Gør det muligt for dig at gennemtvinge planer hurtigt; og,
  5. Sørg for, at dette fungerer på tværs af servergenstarter, opgraderinger og genkompilering af forespørgsler.

Så denne funktion gemmer ikke kun planerne og relaterede oplysninger om forespørgselsydeevne, men kan også hjælpe dig med nemt at gennemtvinge en gammel forespørgselsplan, som i mange tilfælde kan løse et ydeevneproblem.

Sådan bruger du Query Store

Du skal aktivere Query Store ved at bruge ALTER DATABASE CURRENT SET QUERY_STORE = ON; udmelding. Jeg prøvede det i mit nuværende SQL Azure-abonnement, men sætningen returnerede en fejl, da det ser ud til, at funktionen ikke er tilgængelig endnu. Jeg kontaktede Conor, og han fortalte mig, at funktionen snart vil være tilgængelig.

Når Query Store er aktiveret, begynder den at indsamle planerne og forespørgselsydeevnedata, og du kan analysere disse data ved at se på Query Store-tabellerne. Jeg kan i øjeblikket se disse tabeller på SQL Azure, men da jeg ikke var i stand til at aktivere Query Store, returnerede katalogerne ingen data.

Du kan analysere de indsamlede oplysninger enten proaktivt for at forstå ændringerne i forespørgselsydeevnen i din applikation eller med tilbagevirkende kraft, hvis du har et ydeevneproblem. Når du har identificeret problemet, kan du bruge traditionelle forespørgselsindstillingsteknikker til at prøve at løse problemet, eller du kan bruge sp_query_store_force_plan gemt procedure for at gennemtvinge en tidligere plan. Planen skal fanges i Query Store for at blive tvunget, hvilket naturligvis betyder, at den er en gyldig plan (i det mindste da den blev indsamlet; mere om det senere), og den blev genereret af forespørgselsoptimeringsværktøjet før. For at gennemtvinge en plan skal du bruge plan_id , tilgængelig i sys.query_store_plan katalog. Når du ser på de forskellige gemte metrics, som minder meget om det, der er gemt for eksempel i sys.dm_exec_query_stats , kan du træffe beslutningen om at optimere til en bestemt metrik, såsom CPU, I/O osv. Så kan du blot bruge en erklæring som denne:

EXEC sys.sp_query_store_force_plan @query_id = 1, @plan_id = 1;

Dette fortæller SQL Server om at tvinge plan 1 på forespørgsel 1. Teknisk kunne du gøre det samme ved at bruge en planvejledning, men det ville være mere kompliceret, og du ville være nødt til manuelt at indsamle og finde den nødvendige plan i første omgang.

Hvordan fungerer Query Store?

Faktisk at tvinge en plan bruger planvejledninger i baggrunden. Conor nævnte, at "når du kompilerer en forespørgsel, tilføjer vi implicit et USE PLAN-tip med fragmentet af XML-planen, der er knyttet til den erklæring." Så du behøver ikke længere bruge en planvejledning længere. Husk også på, at det, på samme måde som at bruge en planvejledning, ikke er garanteret at have præcis den tvungne plan, men i det mindste noget der ligner den. For en påmindelse om, hvordan planvejledninger fungerer, tag et kig på denne artikel. Derudover skal du være opmærksom på, at der er nogle tilfælde, hvor det ikke virker at tvinge en plan, et typisk eksempel er, når skemaet er ændret, dvs. hvis en lagret plan bruger et indeks, men indekset ikke længere eksisterer. I dette tilfælde kan SQL Server ikke gennemtvinge planen, vil udføre en normal optimering, og den vil registrere det faktum, at forceringen af ​​planen mislykkedes i sys.query_store_plan katalog.

Arkitektur

Hver gang SQL Server kompilerer eller udfører en forespørgsel, sendes en besked til Query Store. Dette vises næste gang.

Oversigt over forespørgselsbutiksworkflow

Kompilerings- og udførelsesoplysningerne opbevares først i hukommelsen og gemmes derefter på disken, afhængigt af Query Store-konfigurationen (dataene aggregeres i henhold til INTERVAL_LENGTH_MINUTES parameter, som som standard er en time, og tømmes til disk i henhold til DATA_FLUSH_INTERVAL_SECONDS parameter). Dataene kan også skylles til disken, hvis der er hukommelsestryk på systemet. Under alle omstændigheder vil du være i stand til at få adgang til alle data, både i hukommelsen og disken, når du kører sys.query_store_runtime_stats katalog.

Kataloger

De indsamlede data bevares på disken og gemmes i brugerdatabasen, hvor Query Store er aktiveret (og indstillinger gemmes i sys.database_query_store_options . Query Store-katalogerne er:

sys.query_store_query_text Forespørgselstekstoplysninger
sys.query_store_query Forespørgselstekst plus den brugte plan, der påvirker SET-indstillingerne
sys.query_store_plan Udførelsesplaner, inklusive historik
sys.query_store_runtime_stats Forespørg efter runtime-statistik
sys.query_store_runtime_stats_interval Start- og sluttidspunkt for intervaller
sys.query_context_settings Forespørg efter oplysninger om kontekstindstillinger

Forespørgselsbutiksvisninger

Runtime-statistikker fanger en hel række af metrikker, inklusive gennemsnit, sidste, min, maks. og standardafvigelse. Her er det fulde sæt af kolonner for sys.query_store_runtime_stats :

runtime_stats_id plan_id runtime_stats_interval_id
execution_type execution_type_desc first_execution_time last_execution_time count_executions
avg_duration last_duration min_duration max_duration stdev_duration
avg_cpu_time last_cpu_time min_cpu_time max_cpu_time stdev_cpu_time
avg_logical_io_reads last_logical_io_reads min_logical_io_reads max_logical_io_reads stdev_logical_io_reads
avg_logical_io_writes last_logical_io_writes min_logical_io_writes max_logical_io_writes stdev_logical_io_writes
avg_physical_io_reads last_physical_io_reads min_physical_io_reads max_physical_io_reads stdev_physical_io_reads
avg_clr_time last_clr_time min_clr_time max_clr_time stdev_clr_time
avg_dop last_dop min_dop max_dop stdev_dop
avg_query_max_used_memory last_query_max_used_memory min_query_max_used_memory max_query_max_used_memory stdev_query_max_used_memory
avg_rowcount last_rowcount min_rowcount max_rowcount stdev_rowcount

Kolonner i sys.query_store_runtime_stats

Disse data fanges kun, når forespørgselsudførelsen slutter. Forespørgselsbutikken tager også hensyn til forespørgslens SET muligheder, som kan påvirke valget af en eksekveringsplan, da de påvirker ting som resultaterne af at evaluere konstante udtryk under optimeringsprocessen. Jeg dækker dette emne i et tidligere indlæg.

Konklusion

Dette vil helt sikkert være en fantastisk funktion og noget, jeg gerne vil prøve så hurtigt som muligt (i øvrigt viser Conors demo "SQL Server 15 CTP1", men disse bits er ikke offentligt tilgængelige). Forespørgselslageret kan være nyttigt til opgraderinger, som kunne være en CU-, servicepakke- eller SQL Server-version, da du kan analysere de oplysninger, der indsamles af forespørgselslageret før og efter for at se, om en forespørgsel er gået tilbage. (Og hvis funktionen er tilgængelig i lavere udgaver, kan du endda gøre dette i et SKU-opgraderingsscenarie.) At vide dette kan hjælpe dig med at tage nogle specifikke handlinger afhængigt af problemet, og en af ​​disse løsninger kunne være at gennemtvinge den tidligere plan som forklaret før.


  1. Kommandoer ude af synkronisering; du kan ikke køre denne kommando nu

  2. MySQL kopidatabase

  3. SQL er ikke en enkeltgruppegruppefunktion

  4. Flere INSERT-sætninger vs. enkelt INSERT med flere VALUES