Database
 sql >> Database >  >> RDS >> Database

Profilatura delle query adatta alla larghezza di banda per il database SQL di Azure

SQL Server ha sempre offerto la possibilità di acquisire query in tempo reale su base ad hoc in un formato di set di righe di facile utilizzo, prima con SQL Server Profiler legacy, successivamente tramite eventi estesi in SSMS. Questa funzionalità è preziosa durante l'ottimizzazione delle prestazioni poiché gli eventi di query includono metriche CPU e IO discrete, nonché parametri di runtime, che sono fondamentali per la risoluzione dei problemi di prestazioni delle query come lo sniffing dei parametri. Inoltre, gli eventi di query contengono altri elementi importanti come il nome host del client, il nome dell'applicazione, il login, l'ID processo di Windows, ecc.

Puoi sempre recuperare aggregato metriche di rendimento per normalizzato query da DMV o Query Store, ma contengono solo compilate parametri e nessuno dei suddetti elementi. Anche se questo è utile, non è la stessa cosa. Ad esempio, se hai bisogno di vedere la combinazione di parametri specifica utilizzata da quella query che ha eseguito 2 miliardi di letture o di trovare l'applicazione che consuma più CPU nelle ultime 24 ore, sei sfortunato.

Il database SQL di Azure non è supportato dal Profiler legacy e Microsoft ha disabilitato il provider di streaming XEvents (sys.fn_MSxe_read_event_stream TVF) per motivi di affidabilità, quindi non è possibile avviare una sessione XE e "guardare i dati in tempo reale" con SSMS. Query Performance Insights nel portale di Azure è supportato da Query Store, quindi hai di nuovo solo le query normalizzate e i dati aggregati sulle prestazioni, non gli eventi di query effettivi.

Quindi, per alcuni anni siamo rimasti bloccati:l'unica opzione per la profilatura del database SQL di Azure è stata quella di creare manualmente una traccia XEvents che scrive in un buffer ad anello o in una destinazione di file con Archiviazione di Azure, nessuno dei quali è ottimale. L'uso del buffer ad anello con le query T-SQL può essere problematico a causa del limite XML formattato di 4 MB, come illustrato da Jonathan Kehayias qui, e le destinazioni dei file richiedono una discreta quantità di salti a cerchio e spese aggiuntive. Entrambi richiedono l'interrogazione manuale dei dati XE e quindi non sono esattamente "live" nel senso tradizionale.

Inserisci il Nuovo Profilo di SQL Server

Quando ho appreso dell'estensione SQL Server Profiler per Azure Data Studio, sono stato lieto di vedere che Microsoft ha finalmente fornito una soluzione grafica per l'acquisizione di query in tempo reale sul database SQL di Azure. Sfortunatamente, la mia eccitazione è stata di breve durata per un paio di motivi.

Innanzitutto, la temuta traccia "Standard" di Profiler legacy è stata apparentemente utilizzata come modello per la sessione XE di ADS Profiler per il database SQL di Azure , denominato ADS_Standard_Azure per impostazione predefinita. (Le sessioni XE utilizzate per SQL Server completo sono simili.) Poiché ho bloggato diversi anni fa e credo ancora, la traccia Standard è una delle ragioni principali per cui il Profiler legacy è così poco considerato. Contiene più eventi inutili e non filtrabili come avvio batch SQL , accedi e disconnessione , e di conseguenza non aggiunge alcun valore reale per l'ottimizzazione delle prestazioni. Inoltre, con l'architettura di traccia del set di righe sincrona utilizzata da Profiler legacy, l'elevato volume di eventi può influire sulle prestazioni dei sistemi occupati. Per qualche ragione questa cosa non andrà via!

Eventi di traccia "Standard" di Profiler legacy

Eventi XE "ADS_Standard_Azure" di ADS Profiler
– vi sembrano familiari?

In secondo luogo, utilizza un buffer ad anello con una dimensione massima di 8 MB o 1000 eventi, a seconda dell'evento che si verifica per primo. Poiché gli eventi di login/logout sono piccoli, spesso raggiungerai 1000 eventi molto prima di raggiungere il limite di 8 MB, o anche il limite XML formattato di 4 MB. Tuttavia, con un mix moderato di eventi SQL, il ring buffer XML sarà ancora da 2 a 3 MB a 1000 eventi nei miei test e il problema è che l'intero buffer viene trascinato attraverso la rete ogni volta che l'estensione Profiler esegue il polling per l'aggiornamento la sua griglia , che è il più lungo di ogni secondo o durata del sondaggio precedente. L'XML viene quindi analizzato lato client dall'estensione ADS Profiler per determinare quali eventi sono nuovi dall'ultimo sondaggio e i nuovi eventi vengono aggiunti alla griglia.

Il buffer ad anello si riempie quasi istantaneamente anche su un server moderatamente occupato e l'effetto netto è che trarrai rapidamente>40 megabit al secondo attraverso la rete dal tuo database SQL di Azure . Questo si traduce in 300 megabyte al minuto o 18 gigabyte all'ora!

Raccolta di rete dall'estensione ADS Profiler (intervallo di 4 minuti)

Il mio timore iniziale era che ciò potesse portare a enormi addebiti in uscita sulla prossima fattura di Azure, tuttavia, esaminando le nostre sottoscrizioni di Azure non siamo stati in grado di confermare che il traffico di rete per Azure SQL DB venga addebitato. Mike Wood (b|t) di SentryOne, un MVP di Azure, ha trascorso settimane cercando di trovare la risposta e alla fine è stato informato da Microsoft che in realtà l'uscita di rete non è attualmente addebitata per Azure SQL DB, anche se questo potrebbe cambiare in qualsiasi momento. Anche così, eliminare 18 GB di dati di query all'ora non sembra responsabile e potrebbe sicuramente mettere un freno alla tua prossima sessione di binge-watching Netflix.

Sebbene tu possa impostare filtri tramite l'interfaccia utente di Profiler che faciliterà la revisione dei dati, non ridurrà l'impatto sulla rete poiché operano sul lato client.

Una sessione XE aggiornata

Una soluzione rapida per ridurre il carico di rete di ADS Profiler e rendere i dati molto più utilizzabili per l'ottimizzazione delle prestazioni delle query consiste nell'aggiornare ADS_Standard_Azure sessione XE. Di seguito è riportato uno script che:

  • Elimina gli eventi inutili:

    • sqlserver.attenzione
    • sqlserver.existing_connection
    • sqlserver.login
    • sqlserver.logout
    • sqlserver.sql_batch_starting
  • Imposta una soglia di durata> 1 secondo (1000000 microsecondi) sugli eventi rimanenti:

    • sqlserver.rpc_completed
    • sqlserver.sql_batch_completed
  • Riduci la dimensione massima del buffer dell'anello da 1000 a 10 eventi

    • Questo non funzionerebbe mai con la traccia originale poiché verranno generati 10 eventi in millisecondi e il buffer dell'anello si ricicli troppo rapidamente causando la perdita della maggior parte degli eventi. Tuttavia, con il filtro della durata di 1 secondo, il flusso di eventi sarà molto più basso e 10 eventi dovrebbero funzionare bene con l'intervallo di polling di 1 secondo utilizzato da ADS Profiler.
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

Dopo aver applicato lo script per aggiornare la sessione XE, la manichetta sarà immediatamente ridotta a un rivolo:

Colpo di rete ridotto dopo l'aggiornamento della sessione XE di ADS Profiler

Alternative ancora più leggere

SQL Sentry e la sua controparte SaaS SentryOne Monitor sono le uniche altre soluzioni che conosco per l'acquisizione di query dal database SQL di Azure e lo fanno utilizzando un approccio innovativo notevolmente più leggero rispetto alla sessione XE ottimizzata sopra per ADS Profiler. Tra le altre funzionalità avanzate, puoi facilmente aggregare per nome host del client, applicazione e login e acquisire automaticamente piani di query per l'analisi con Plan Explorer integrato.

SentryOne Monitor che mostra le query e i piani acquisiti dal database SQL di Azure

Chiusura

Microsoft ha dichiarato che continuerà a migliorare l'estensione ADS Profiler e, quando lo farà, spero che risolverà i problemi descritti sopra. Ho registrato il problema qui. Nel frattempo, lo script aggiornato renderà l'esperienza di profilatura delle query più sicura e più adatta alla larghezza di banda per il database SQL di Azure.