sql >> Database >  >> RDS >> Database

Bandbreedtevriendelijke queryprofilering voor Azure SQL Database

SQL Server heeft altijd de mogelijkheid geboden om live-query's op ad-hocbasis vast te leggen in een gemakkelijk te consumeren rowset-indeling - eerst met legacy SQL Server Profiler, later via Extended Events in SSMS. Deze mogelijkheid is waardevol bij het afstemmen van prestaties, aangezien query-gebeurtenissen discrete CPU- en IO-statistieken bevatten, evenals runtime-parameters, die essentieel zijn voor het oplossen van problemen met queryprestaties, zoals het snuiven van parameters. Verder bevatten query-gebeurtenissen andere belangrijke elementen, zoals de hostnaam van de client, de naam van de toepassing, aanmelding, Windows-proces-ID, enz.

U kunt altijd geaggregeerd ophalen prestatiestatistieken voor genormaliseerd zoekopdrachten van DMV's of Query Store, maar ze bevatten alleen gecompileerde parameters en geen van de bovengenoemde elementen. Hoewel dit nuttig is, is het niet hetzelfde. Als u bijvoorbeeld de specifieke parametercombinatie wilt zien die is gebruikt door die zoekopdracht die 2 miljard keer is gelezen of de meest CPU-verbruikende applicatie van de afgelopen 24 uur moet vinden, heeft u pech.

Azure SQL Database wordt niet ondersteund door verouderde Profiler en Microsoft heeft de XEvents-streamingprovider (sys.fn_MSxe_read_event_stream TVF) om betrouwbaarheidsredenen uitgeschakeld, dus u kunt geen XE-sessie starten en "live gegevens bekijken" met SSMS. Query Performance Insights in de Azure Portal wordt ondersteund door Query Store, dus u hebt weer alleen de genormaliseerde query's en geaggregeerde prestatiegegevens, niet de daadwerkelijke querygebeurtenissen.

Dus een paar jaar zaten we vast - de enige optie voor het profileren van Azure SQL Database was om handmatig een XEvents-tracering te maken die naar een ringbuffer of bestandsdoel schrijft met Azure Storage, die geen van beide optimaal zijn. Het gebruik van de ringbuffer met T-SQL-query's kan problematisch zijn vanwege de 4 MB geformatteerde XML-limiet zoals beschreven door Jonathan Kehayias hier, en bestandsdoelen vereisen behoorlijk wat hoepelspringen en extra kosten. Beide vereisen handmatige bevraging van de XE-gegevens en zijn dus niet echt "live" in de traditionele zin.

Voer de Nieuw in SQL Server-profiler

Toen ik hoorde van de SQL Server Profiler-extensie voor Azure Data Studio, was ik verheugd te zien dat Microsoft eindelijk een grafische oplossing leverde voor het live vastleggen van query's op Azure SQL Database. Helaas was mijn opwinding om een ​​aantal redenen van korte duur.

Ten eerste is de gevreesde "Standaard"-trace van legacy Profiler blijkbaar gebruikt als model voor de ADS Profiler XE-sessie voor Azure SQL Database , genaamd ADS_Standard_Azure standaard. (De XE-sessies die voor volledige SQL Server worden gebruikt, zijn vergelijkbaar.) Zoals ik een aantal jaren geleden heb geblogd en nog steeds geloof, is de standaardtracering de belangrijkste reden waarom legacy Profiler zo slecht wordt beschouwd. Het bevat meerdere nutteloze en onfilterbare gebeurtenissen, zoals het starten van SQL-batch , aanmelden en uitloggen , en als gevolg daarvan voegt het geen echte waarde toe voor het afstemmen van prestaties. Bovendien kan het hoge gebeurtenisvolume, met de synchrone rowset-traceerarchitectuur die wordt gebruikt door legacy Profiler, de prestaties op drukke systemen beïnvloeden. Om de een of andere reden zal dit ding niet verdwijnen!

Legacy Profiler "Standaard" traceergebeurtenissen

ADS Profiler "ADS_Standard_Azure" XE-evenementen
– ziet u er bekend uit?

Ten tweede gebruikt het een ringbuffer met een maximale grootte van 8 MB of 1000 gebeurtenissen, afhankelijk van wat zich het eerst voordoet. Omdat de in- en uitloggebeurtenissen klein zijn, bereikt u vaak 1000 gebeurtenissen lang voordat u de 8 MB-limiet bereikt, of zelfs de 4 MB-geformatteerde XML-limiet. Met een matige mix van SQL-gebeurtenissen zal de XML-ringbuffer-XML echter nog steeds 2 tot 3 MB zijn bij 1000 gebeurtenissen in mijn testen, en het probleem is dat deze hele buffer over het netwerk wordt getrokken telkens wanneer de Profiler-extensie pollt om te vernieuwen zijn raster , wat de langste is van elke seconde of duur van de vorige peiling. De XML wordt vervolgens aan de clientzijde geparseerd door de ADS Profiler-extensie om te bepalen welke gebeurtenissen nieuw zijn sinds de laatste peiling, en de nieuwe gebeurtenissen worden aan het raster toegevoegd.

De ringbuffer loopt bijna onmiddellijk vol, zelfs op een redelijk drukke server, en het netto-effect is dat u snel>40 megabits per seconde over het netwerk haalt uit uw Azure SQL Database . Dit vertaalt zich naar 300 megabyte per minuut, of 18 gigabyte per uur!

Netwerkhit van de ADS Profiler-extensie (bereik van 4 minuten)

Mijn aanvankelijke angst was dat dit zou kunnen leiden tot enorme kosten voor uitgaand verkeer op de volgende Azure-factuur, maar als we naar onze eigen Azure-abonnementen kijken, konden we niet bevestigen dat netwerkverkeer voor Azure SQL DB in rekening wordt gebracht. Mike Wood (b|t) van SentryOne, een Azure MVP, heeft wekenlang geprobeerd het antwoord te vinden en kreeg uiteindelijk van Microsoft te horen dat er momenteel inderdaad geen kosten in rekening worden gebracht voor uitgaand netwerkverkeer voor Azure SQL DB, hoewel dit op elk moment kan veranderen. Toch lijkt het niet verantwoord om 18 GB aan zoekgegevens per uur naar beneden te halen, en het zou zeker een domper kunnen zijn op je volgende Netflix-binge-watching-sessie.

Hoewel u filters kunt instellen via de gebruikersinterface van Profiler, waardoor de gegevens gemakkelijker te bekijken zijn, wordt de netwerkhit niet verminderd omdat ze aan de clientzijde werken.

Een bijgewerkte XE-sessie

Een snelle oplossing om de netwerkbelasting van ADS Profiler te verminderen en de gegevens veel meer verbruikbaar te maken voor het afstemmen van queryprestaties, is het bijwerken van de ADS_Standard_Azure XE-sessie. Hieronder staat een script dat:

  • Verwijder de nutteloze gebeurtenissen:

    • sqlserver.attention
    • sqlserver.existing_connection
    • sqlserver.login
    • sqlserver.logout
    • sqlserver.sql_batch_starting
  • Stel een drempelwaarde in van> 1 seconde (1000000 microseconden) voor de resterende gebeurtenissen:

    • sqlserver.rpc_completed
    • sqlserver.sql_batch_completed
  • Verklein de maximale grootte van de ringbuffer van 1000 naar 10 gebeurtenissen

    • Dit zou nooit werken met de originele trace, aangezien 10 gebeurtenissen in milliseconden worden gegenereerd en de ringbuffer te snel zou recyclen, waardoor de meeste gebeurtenissen verloren zouden gaan. Met het 1-seconde duurfilter zal de gebeurtenisstroom echter veel lager zijn en 10 gebeurtenissen zouden goed moeten werken met het polling-interval van 1 seconde dat door de ADS Profiler wordt gebruikt.
ALTER EVENT SESSION [ADS_Standard_Azure] ON DATABASE 
DROP EVENT sqlserver.attention,
DROP EVENT sqlserver.existing_connection,
DROP EVENT sqlserver.login,
DROP EVENT sqlserver.logout,
DROP EVENT sqlserver.rpc_completed,
DROP EVENT sqlserver.sql_batch_completed,
DROP EVENT sqlserver.sql_batch_starting
GO
 
ALTER EVENT SESSION [ADS_Standard_Azure] ON DATABASE 
ADD EVENT sqlserver.rpc_completed(
ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.client_pid,sqlserver.database_id,sqlserver.query_hash,sqlserver.session_id,sqlserver.username)
      WHERE (([package0].[equal_boolean]([sqlserver].[is_system],(0))) AND ([duration] >= (1000000)))),
ADD EVENT sqlserver.sql_batch_completed(
ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.client_pid,sqlserver.database_id,sqlserver.query_hash,sqlserver.session_id,sqlserver.username)
      WHERE (([package0].[equal_boolean]([sqlserver].[is_system],(0))) AND ([duration] >= (1000000))))
GO
 
ALTER EVENT SESSION [ADS_Standard_Azure] ON DATABASE 
DROP TARGET package0.ring_buffer
GO
 
ALTER EVENT SESSION [ADS_Standard_Azure] ON DATABASE 
ADD TARGET package0.ring_buffer(SET max_events_limit=(10),max_memory=(51200))
GO

Na het toepassen van het script om de XE-sessie bij te werken, wordt de brandslang onmiddellijk gereduceerd tot een straaltje:

Verminderde netwerkhit na updaten van de ADS Profiler XE-sessie

Nog lichtere alternatieven

SQL Sentry en zijn SaaS-tegenhanger SentryOne Monitor zijn de enige andere oplossingen die ik ken voor het vastleggen van query's uit Azure SQL Database, en ze doen dit met een innovatieve aanpak die aanzienlijk lichter is dan de hierboven geoptimaliseerde XE-sessie voor ADS Profiler. Naast andere geavanceerde functies kunt u eenvoudig aggregeren op client-hostnaam, applicatie en login, en automatisch queryplannen vastleggen voor analyse met de geïntegreerde Plan Explorer.

SentryOne Monitor toont vastgelegde query's en plannen van Azure SQL Database

Afsluiten

Microsoft heeft verklaard dat ze de ADS Profiler-extensie zullen blijven verbeteren, en als ze dat doen, hoop ik dat ze de hierboven beschreven problemen zullen aanpakken. Ik heb het probleem hier geregistreerd. In de tussentijd zorgt het bijgewerkte script voor een veiligere en meer bandbreedtevriendelijke queryprofileringservaring voor Azure SQL Database.


  1. KIES * WAAR NIET BESTAAT

  2. Vraagfout met dubbelzinnige kolomnaam in SQL

  3. FOUT 2006 (HY000):MySQL-server is verdwenen

  4. Wat is de beste manier om de eerste letter van elk woord in een tekenreeks in SQL Server met een hoofdletter te schrijven?