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

Virkningen af ​​query_post_execution_showplan Extended Event i SQL Server 2012

En af de hårdeste udfordringer i SQL Server er fejlfinding af problemer med parameterfølsomhed eller kardinalitetsestimering, der forårsager ydeevneforringelse af en arbejdsbelastning. Generelt skal du have den faktiske udførelsesplan fra erklæringen kørende for at kunne fastslå årsagen til ydeevneforringelsen. I SQL Server 2012 giver query_post_execution_showplan Extended Event mulighed for at fange den faktiske udførelsesplan for sætninger. Men hvor nyttigt dette end ser ud, er denne hændelse ikke noget, der kan bruges uden en væsentlig indvirkning på ydeevnen på den arbejdsbyrde, der kører på serveren.

I min artikel Måling af "Observer Overhead" af SQL Trace vs. Extended Events viste jeg en sammenligning af effektivitetspåvirkningen af ​​SQL Trace i forhold til en identisk konfiguration ved hjælp af Extended Events i SQL Server 2012.  På det tidspunkt lavede jeg oprindeligt testen for den artikel Jeg testede også meget af hændelsen query_post_execution_showplan i SQL Server 2012.  Denne hændelse blev først introduceret i SQL Server 2012 CTP1, da mange af sporingshændelserne blev overført til Extended Events for at give paritet med SQL Trace. På det tidspunkt havde begivenheden kun et undersæt af kolonnerne, der var inkluderet i den endelige RTM af SQL Server 2012.

Under CTP1 indsendte jeg et Connect-element, der anmodede om, at der oprettes en handling for at tillade indsamling af den faktiske eksekveringsplan med hændelser i SQL Server 2012.  Målet var at kunne bruge hændelserne module_end eller sql_statement_completed til at identificere, hvornår udførelsen af ​​en procedure eller erklæring overskrider sin normale varighed. For eksempel, i scenariet med parameterfølsomhed, hvor der genereres en mindre ideel plan for de normale parameterværdier, kan hændelsen bruges til at indsamle den faktiske udførelsesplan for den erklæring gennem en handling. Som svar tilføjede SQL Server-teamet kolonnerne varighed og cpu_time til hændelsen query_post_execution_showplan for at tillade prædikatdefinitioner kun at indsamle denne hændelse for disse scenarier.

Desværre har dette ikke de samme fordele, som en implementering som en handling ville have haft på ydeevnen. I resten af ​​dette indlæg vil jeg forklare hvorfor.

Ydeevnepåvirkning

På det tidspunkt, hvor jeg testede min tidligere artikel, testede jeg også de overhead, der var forbundet med query_post_execution_showplan-begivenheden, primært fordi jeg virkelig var interesseret i at bruge den i et par klientproduktionssystemer, og før jeg gjorde det, var jeg nødt til at forstå, hvad slags indflydelse begivenheden ville have på deres arbejdsbyrde. Jeg var virkelig forfærdet over de resultater, jeg fik fra mine originale tests, og efter at have fået Aaron Bertrand til at validere mine resultater ved hjælp af SQL Sentrys interne testsele, indgav jeg endnu et Connect-element, der rapporterede ydeevneproblemerne, som efterfølgende er blevet lukket som "By Design" .

Til afprøvning af ydeevnepåvirkningen blev den nøjagtig samme arbejdsbyrde og Distributed Replay-konfiguration fra artiklen Måling af "Observer Overhead" af SQL Trace vs. Extended Events brugt. Den eneste forskel for testresultaterne vist i denne artikel er, at et nyere, mere kraftfuldt værtssystem blev brugt til VM-miljøet. De anvendte VM'er var nøjagtig de samme, uden ændringer i deres konfiguration, og de blev simpelthen kopieret til det nye system, hvilket er grunden til, at baseline-arbejdsbelastningen var i stand til at udføre gentagelsen hurtigere med et højere gennemsnit af Batch-anmodninger/sek. Baseline-resultaterne blev fanget ved hjælp af en standard SQL Server 2012-installation, hvor kun standard system_health-hændelsessessionen kørte på serveren.

Til sammenligning af ydeevnepåvirkningen af ​​query_post_execution_showplan begivenhed blev følgende definition af begivenhedssession brugt.

CREATE EVENT SESSION [query_post_execution_showplan Overhead]
ON SERVER
ADD EVENT sqlserver.query_post_execution_showplan(
WHERE ([duration]=(5000000)));
GO

Denne session indsamler faktisk ikke hændelsesdata ved hjælp af et mål og bruger et prædikat på varigheden for hændelsens varighed er lig med 5000000 mikrosekunder eller fem sekunders varighed. For replay-arbejdsbelastningen har ingen udførelse af sætninger en varighed på præcis fem sekunder, så hændelsen query_post_execution_showplan udløses faktisk aldrig på serveren, og enhver ydeevneforringelse er udelukkende resultatet af hændelsesdataindsamlingen og derefter prædikatevalueringen. Resultaterne fra testene er vist i tabel 1 og kortlagt i diagram 2.


Tabel 1 – query_post_execution hændelsesoverhead


Diagram 2 – query_post_execution hændelse overhead

For denne testrunde forringes arbejdsbelastningens ydeevne med omkring 30 % ved blot at have denne begivenhed aktiveret i en begivenhedssession, selvom den ikke udløses for nogen af ​​de begivenheder, der afspilles igen på serveren. Den overordnede nedbrydning vil afhænge af den faktiske arbejdsbyrde for serveren, og det er vigtigt at bemærke, at denne serie af test afspejler mere af et worst case-scenarie, da Distributed Replay blev kørt i stress-tilstand, og CPU-bruget på SQL Serveren var tilknyttet. på 94 % i gennemsnit under testene.

Forstå virkningen af ​​ydeevnen

Årsagen til, at denne hændelse pålægger en så betydelig overhead på ydeevnen, kan forklares ud fra hændelsens livscyklus i Extended Events. Når et kritisk punkt i SQL Server-koden, der er knyttet til en hændelse, stødes på under udførelsen, udfører koden en meget hurtig boolsk kontrol for at afgøre, om hændelsen er aktiveret i en aktiv hændelsessession på serveren. Hvis hændelsen er aktiveret for en aktiv hændelsessession, indsamles alle datakolonner, der er knyttet til hændelsen, inklusive alle tilpassede kolonner, der er blevet aktiveret. På dette tidspunkt evaluerer begivenheden eventuelle prædikater for de aktive begivenhedssessioner, der indsamler begivenheden, for at afgøre, om begivenheden rent faktisk udløses fuldstændigt.

For hændelsen query_post_exection_showplan er al effektpåvirkningen fra de overhead, der er knyttet til dataindsamlingen. Selv i det tilfælde, hvor der er et prædikat for en varighed svarende til fem sekunder, bare ved at slå hændelsen til i en hændelsessession, skal den indsamle Showplan XML for hver sætning, der udføres på serveren, bare for at kunne evaluere prædikatet og afgør derefter, at begivenheden ikke udløses. Af denne grund bør hændelsen query_post_execution_showplan undgås for produktionsarbejdsbelastninger. For test-replay-arbejdsbelastningen skulle begivenheden evalueres omkring 440.000 gange, selvom den faktisk ikke udløses for den workload og begivenhedssession, der testes, da ingen af ​​replay-begivenhederne har en varighed på præcis fem sekunder. Hændelsestællingsoplysningerne blev indsamlet ved at føje event_counter-målet til hændelsessessionen og fjerne varighedsprædikatet og derefter genteste genafspilningsarbejdsbelastningen med følgende sessionsdefinition.

CREATE EVENT SESSION [query_post_execution_showplan Overhead] 
ON SERVER
ADD EVENT sqlserver.query_post_execution_showplan
ADD TARGET package0.event_counter;
GO

Sammenligning med hændelser med hurtig udløsning

For at give en referenceramme for denne præstationspåvirkning kan vi se på omkostningerne ved at aktivere et sæt hyppigt eksekverende hændelser på serveren og udføre den samme replay-arbejdsbelastning. To af de hyppigst udførte hændelser i SQL Server er hændelserne lock_acquired og lock_released. For at sammenligne overheaden for disse to hændelser kan den følgende hændelsessession bruges, som samler hændelserne uden prædikat, så hver eksekvering samles og tæller, hvor ofte de skyder ved hjælp af event_counter-målet.

CREATE EVENT SESSION [locking Overhead] 
ON SERVER
ADD EVENT sqlserver.lock_acquired,
ADD EVENT sqlserver.lock_released
ADD TARGET package0.event_counter;
GO

For vores replay-arbejdsbyrde udløses disse to begivenheder omkring 111.180.000 gange. De overhead, der er forbundet med at indsamle disse hændelser, kan ses i tabel 3 og diagram 4.


Tabel 3 – Sammenligning af låseoverhead


Diagram 4 – Overhead-sammenligning af låsehændelser

Som du kan se fra dataene, er ydeevneeffekten af ​​disse hændelser betydeligt lavere end for query_post_execution_showplan, selvom definitionen af ​​låsehændelsessessionen var konfigureret til at tillade alle hændelser at udløse på serveren, var den samlede overhead under 1 % samlet . Husk på, at låsebegivenhedssessionen evaluerede, hvad der svarer til 500 gange flere hændelser, og i dette tilfælde skulle alle hændelser faktisk udløses til hændelsessessionen, hvor query_post_execution_showplan-hændelsen faktisk ikke behøvede at blive udløst efter at være blevet evalueret.

Oversigt

Mens query_post_execution_showplan-hændelsen giver mulighed for at indsamle den faktiske forespørgselsplan for en erklæring, der udføres, gør indvirkningen af ​​dataindsamlingens ydeevne blot for at evaluere hændelsen det til noget, der ikke er levedygtigt for produktionsbrug. Som minimum bør overhead overvejes, før du nogensinde bruger denne begivenhed mod en produktionsbelastning. Selv begivenhedsbeskrivelsen leveret af Microsoft anerkender, at begivenheden kan have en betydelig indvirkning på ydeevnen (min fremhævelse):

Opstår efter at en SQL-sætning er udført. Denne hændelse returnerer en XML-repræsentation af den faktiske forespørgselsplan. Brug af denne hændelse kan have betydelige præstationsomkostninger, så den bør kun bruges til fejlfinding eller overvågning af specifikke problemer i korte perioder.

Begivenhedsbeskrivelsen kan findes i beskrivelseskolonnen i sys.dm_xe_objects-katalogvisningen eller i New Session UI som vist i figur 5 (min fremhævelse):


Figur 5 – Begivenhedsbeskrivelse fra New Session UI

Jeg vil anbefale at benchmarke ydeevnen af ​​enhver hændelse med denne advarsel i beskrivelsen, før den faktisk bruges i et produktionsmiljø.


  1. På opgraderingsmetoden bliver ikke kaldt i android sqlite

  2. MySQL, bedre at indsætte NULL eller tom streng?

  3. Sådan udføres en UPSERT, så jeg kan bruge både nye og gamle værdier i opdateringsdelen

  4. 4 måder at få databasesamlingen i MariaDB