Een van de moeilijkste uitdagingen in SQL Server is het oplossen van problemen met parametergevoeligheid of kardinaliteitsschatting die prestatievermindering van een werkbelasting veroorzaken. Over het algemeen moet u het daadwerkelijke uitvoeringsplan van de instructie hebben uitgevoerd om de oorzaak van de prestatievermindering te kunnen bepalen. In SQL Server 2012 biedt de query_post_execution_showplan Extended Event de mogelijkheid om het daadwerkelijke uitvoeringsplan voor instructies vast te leggen. Hoe nuttig dit ook lijkt, deze gebeurtenis kan niet worden gebruikt zonder een significante invloed op de prestaties van de werkbelasting op de server.
In mijn artikel "Observer Overhead" van SQL Trace vs. Extended Events meten, liet ik een vergelijking zien van de prestatie-impact van SQL Trace met een identieke configuratie met behulp van Extended Events in SQL Server 2012. Destijds deed ik de tests voor dat artikel Ik heb ook veel getest van de query_post_execution_showplan-gebeurtenis in SQL Server 2012. Deze gebeurtenis werd voor het eerst geïntroduceerd in SQL Server 2012 CTP1 toen veel van de trace-gebeurtenissen werden overgedragen naar Extended Events om pariteit met SQL Trace te bieden. Op dat moment had het evenement slechts een subset van de kolommen die waren opgenomen in de uiteindelijke RTM van SQL Server 2012.
Tijdens CTP1 heb ik een Connect-item ingediend met het verzoek een actie te maken om het daadwerkelijke uitvoeringsplan met gebeurtenissen in SQL Server 2012 te kunnen verzamelen. Het doel was om de gebeurtenissen module_end of sql_statement_completed te kunnen gebruiken om te bepalen wanneer de uitvoering van een procedure of verklaring de normale duur overschrijdt. In het scenario van parametergevoeligheid, waarbij een minder ideaal plan wordt gegenereerd voor de normale parameterwaarden, kan de gebeurtenis bijvoorbeeld worden gebruikt om het daadwerkelijke uitvoeringsplan voor die instructie via een actie te verzamelen. Als reactie hierop heeft het SQL Server-team de kolommen duration en cpu_time toegevoegd aan de query_post_execution_showplan-gebeurtenis, zodat predikaatdefinities deze gebeurtenis alleen voor die scenario's kunnen verzamelen.
Helaas heeft dit niet dezelfde voordelen die een implementatie als een actie zou hebben gehad op de prestaties. In de rest van dit bericht zal ik uitleggen waarom.
Prestatie-impact
Op het moment dat ik de tests voor mijn vorige artikel deed, testte ik ook de overhead die verband houdt met de query_post_execution_showplan-gebeurtenis, voornamelijk omdat ik echt geïnteresseerd was om het in een aantal clientproductiesystemen te gebruiken en voordat ik dat deed, moest ik begrijpen wat soort impact die het evenement zou hebben op hun werklast. Ik was echt verbijsterd door de resultaten die ik kreeg van mijn oorspronkelijke tests, en nadat ik Aaron Bertrand mijn resultaten had laten valideren met behulp van het interne testharnas van SQL Sentry, diende ik een ander Connect-item in dat de prestatieproblemen rapporteerde, dat vervolgens werd gesloten als "By Design" .
Voor het testen van de prestatie-impact werd exact dezelfde workload en Distributed Replay-configuratie gebruikt uit het artikel "Observer Overhead" meten van SQL Trace vs. Extended Events. Het enige verschil voor de testresultaten die in dit artikel worden getoond, is dat er een nieuwer, krachtiger hostsysteem is gebruikt voor de VM-omgeving. De gebruikte VM's waren precies hetzelfde, zonder wijzigingen in hun configuratie, en ze werden eenvoudig naar het nieuwe systeem gekopieerd. Daarom kon de baseline-werkbelasting de replay sneller uitvoeren met een hoger gemiddelde batchverzoeken/sec. De basislijnresultaten zijn vastgelegd met behulp van een standaard SQL Server 2012-installatie met alleen de standaard system_health-gebeurtenissessie op de server.
Voor de vergelijking van de prestatie-impact van het query_post_execution_showplan
gebeurtenis, is de volgende gebeurtenissessiedefinitie gebruikt.
CREATE EVENT SESSION [query_post_execution_showplan Overhead] ON SERVER ADD EVENT sqlserver.query_post_execution_showplan( WHERE ([duration]=(5000000))); GO
Deze sessie verzamelt de gebeurtenisgegevens niet echt met behulp van een doel en gebruikt een predikaat voor de duur voor de gebeurtenisduur die gelijk is aan 5000000 microseconden of vijf seconden. Voor de replay-workload heeft geen enkele uitvoering van een instructie een duur van precies vijf seconden, dus de query_post_execution_showplan-gebeurtenis wordt nooit daadwerkelijk op de server geactiveerd, en elke prestatievermindering is strikt het resultaat van de gebeurtenisgegevensverzameling en vervolgens de predikaatevaluatie. De resultaten van de tests worden weergegeven in tabel 1 en in kaart gebracht in grafiek 2.
Tabel 1 – query_post_execution gebeurtenisoverhead
Grafiek 2 – query_post_execution gebeurtenisoverhead
Voor deze testronde nemen de prestaties van de werkbelasting met ongeveer 30% af door deze gebeurtenis eenvoudigweg in een gebeurtenissessie aan te zetten, ook al wordt deze niet geactiveerd voor een van de gebeurtenissen die op de server worden afgespeeld. De algehele degradatie hangt af van de werkelijke werkbelasting voor de server, en het is belangrijk op te merken dat deze reeks tests meer een worstcasescenario weerspiegelt, aangezien de Distributed Replay werd uitgevoerd in de stressmodus en het CPU-gebruik op de SQL Server was gekoppeld gemiddeld 94% tijdens de tests.
De prestatie-impact begrijpen
De reden dat deze gebeurtenis zo'n aanzienlijke overhead op de prestaties met zich meebrengt, kan worden verklaard uit de gebeurtenislevenscyclus in Extended Events. Wanneer een kritiek punt in de SQL Server-code dat aan een gebeurtenis is gekoppeld, wordt aangetroffen tijdens de uitvoering, voert de code een zeer snelle Booleaanse controle uit om te bepalen of de gebeurtenis is ingeschakeld in een actieve gebeurtenissessie op de server. Als de gebeurtenis is ingeschakeld voor een actieve gebeurtenissessie, worden alle gegevenskolommen die aan de gebeurtenis zijn gekoppeld verzameld, inclusief eventuele aanpasbare kolommen die zijn ingeschakeld. Op dit punt evalueert de gebeurtenis alle predikaten voor de actieve gebeurtenissessies die de gebeurtenis verzamelen om te bepalen of de gebeurtenis daadwerkelijk volledig wordt geactiveerd.
Voor de query_post_exection_showplan-gebeurtenis is alle prestatie-impact afkomstig van de overhead die is gekoppeld aan de gegevensverzameling. Zelfs in het geval dat er een predikaat is voor duur gelijk aan vijf seconden, moet het gewoon door de gebeurtenis in een gebeurtenissessie aan te zetten de Showplan XML verzamelen voor elke instructie die op de server wordt uitgevoerd om het predikaat te kunnen evalueren en stel vervolgens vast dat de gebeurtenis niet wordt geactiveerd. Om deze reden moet de gebeurtenis query_post_execution_showplan worden vermeden voor productieworkloads. Voor de test replay-workload moest de gebeurtenis ongeveer 440.000 keer worden geëvalueerd, hoewel het niet echt wordt geactiveerd voor de workload en de gebeurtenissessie die wordt getest, aangezien geen van de replay-gebeurtenissen een duur van precies vijf seconden heeft. De informatie over het aantal gebeurtenissen is verzameld door het doel event_counter toe te voegen aan de gebeurtenissessie en het predikaat duur te verwijderen en vervolgens de herhalingswerkbelasting opnieuw te testen met de volgende sessiedefinitie.
CREATE EVENT SESSION [query_post_execution_showplan Overhead] ON SERVER ADD EVENT sqlserver.query_post_execution_showplan ADD TARGET package0.event_counter; GO
Vergelijking met snel vurende gebeurtenissen
Om een referentiekader voor deze prestatie-impact te bieden, kunnen we kijken naar de overhead van het inschakelen van een reeks frequent uitgevoerde gebeurtenissen op de server en het uitvoeren van dezelfde replay-workload. Twee van de meest frequent uitgevoerde gebeurtenissen in SQL Server zijn de gebeurtenissen lock_acquired en lock_released. Om de overhead van deze twee gebeurtenissen te vergelijken, kan de volgende gebeurtenissessie worden gebruikt, die de gebeurtenissen verzamelt zonder predikaat, zodat elke uitvoering wordt verzameld en telt hoe vaak ze worden geactiveerd met behulp van het event_counter-doel.
CREATE EVENT SESSION [locking Overhead] ON SERVER ADD EVENT sqlserver.lock_acquired, ADD EVENT sqlserver.lock_released ADD TARGET package0.event_counter; GO
Voor onze replay-werklast vuren deze twee gebeurtenissen ongeveer 111.180.000 keer. De overhead die gepaard gaat met het verzamelen van deze gebeurtenissen is te zien in Tabel 3 en Grafiek 4.
Tabel 3 – Overheadvergelijking vergrendelen
Grafiek 4 – Overheadvergelijking van gebeurtenissen vergrendelen
Zoals u aan de gegevens kunt zien, is het prestatie-effect van deze gebeurtenissen aanzienlijk lager dan voor query_post_execution_showplan, hoewel de sessiedefinitie van de vergrendelingsgebeurtenis zo is geconfigureerd dat alle gebeurtenissen op de server kunnen worden geactiveerd, was de totale overhead in totaal minder dan 1% . Houd er rekening mee dat de vergrendelingsgebeurtenissessie het equivalent van 500 keer meer gebeurtenissen heeft geëvalueerd, en in dit geval moesten alle gebeurtenissen daadwerkelijk worden geactiveerd voor de gebeurtenissessie, waar de query_post_execution_showplan-gebeurtenis niet echt hoefde te worden geactiveerd nadat deze was geëvalueerd.
Samenvatting
Hoewel de gebeurtenis query_post_execution_showplan de mogelijkheid biedt om het daadwerkelijke queryplan te verzamelen voor een instructie die wordt uitgevoerd, maakt de prestatie-impact van de gegevensverzameling alleen om de gebeurtenis te evalueren het iets dat niet haalbaar is voor productiegebruik. Er moet op zijn minst rekening worden gehouden met de overhead voordat u deze gebeurtenis ooit gebruikt tegen een productiewerkbelasting. Zelfs de gebeurtenisbeschrijving van Microsoft erkent dat de gebeurtenis een aanzienlijke prestatie-impact kan hebben (mijn markering):
Treedt op nadat een SQL-instructie is uitgevoerd. Deze gebeurtenis retourneert een XML-representatie van het werkelijke queryplan. Het gebruik van deze gebeurtenis kan een aanzienlijke prestatie-overhead met zich meebrengen, dus het mag alleen worden gebruikt bij het oplossen van problemen of het bewaken van specifieke problemen voor een korte periode.De gebeurtenisbeschrijving is te vinden in de beschrijvingskolom van de catalogusweergave sys.dm_xe_objects, of in de gebruikersinterface voor nieuwe sessies zoals weergegeven in afbeelding 5 (mijn markering):
Figuur 5 – Gebeurtenisbeschrijving van de nieuwe sessie-UI
Ik zou aanraden om de prestaties van een evenement te benchmarken met deze waarschuwing in de beschrijving voordat je het daadwerkelijk in een productieomgeving gebruikt.