Perché query_hash è zero per le istruzioni EXEC?


8

Sto configurando un sistema di monitoraggio per SQL Server utilizzando gli eventi estesi per trovare query pesanti come "feedback sulla produzione" per i nostri sviluppatori. Sto usando gli eventi sp_statement_completede sql_statement_completed, con filtri predicati su cpu_time, letture logiche, ecc. Speravo di aggregare i risultati database_namee query_hashcome dimostrato in numerosi esempi su Internet, ma nei risultati vedo che query_hashè 0 per tutte le affermazioni usando EXEC, come nella tabella seguente (timestamp e queryhash abbreviati per leggibilità).

name                       timestamp      query_hash plan_handle        statement
sql_statement_completed    2016...6414    0          050056019600764... exec Shared.dbo.SyncFirm  
sql_statement_completed    2016...9946    0          06003d00e01e730... exec spSetUserAuth @userid;  
sql_statement_completed    2016...7184    0          0600e30028c9da0... exec spSetUserAuth @userid;  
sp_statement_completed     2016...0409    9826...578 0600c00028e6aa0... SELECT obfuscated_columns FROM dbo.SomeTable
sp_statement_completed     2016...1448    8660...775 060084006d2d660... INSERT INTO dbo.SomeTable ( obfuscated_columns)  EXEC(@sql)
sql_statement_completed    2016...7752    0          0600f9006c23f03... exec spSetUserAuth @userid;  
sql_statement_completed    2016...1443    1304...641 06005a0008a9b11... select SUBQ.ontrackstatus, COUNT(SUBQ.ontrac

Tutti i risultati hanno un valore per plan_handlee sono tutti diversi, quindi vengono generati molti piani. Altre dichiarazioni senza query_hash(che ho visto) includono ALTER INDEX, CHECKPOINT, AGGIORNAMENTO STATISTICHE, COMMIT TRANSACTION, FETCH NEXT FROM Cursor, alcuni INSERT, SELECT @variable, IF (@variable = x).

Qualcuno sa perché query_hashè 0? Probabilmente mi manca il punto da qualche parte su SQL Query Analyzer ed EXEC, ma non sono in grado di trovare indizi per indirizzarmi nella giusta direzione. Se i risultati che sto ottenendo sono "normali", come aggregare al meglio i risultati? Il raggruppamento per istruzione non include letterali, spazi bianchi, ecc. Che vengono rimossi quando si calcola query_hash?

EDIT: come lo vedo ora, EXEC SomeStoredProcedureavvia una procedura memorizzata (ovvia) e le singole istruzioni in quella procedura memorizzata finiscono nella sessione dell'evento come sp_statement_completedeventi, e tutte hanno una query_hash.

Quindi, per sp_statement_completed(cioè query "reali"), posso aggregare su query_hash e database_name e, sql_statement_completedsenza query_hash (EXEC SomeStoredProcedure), posso usare il client_connection_idper raggruppare le istruzioni all'interno di un'esecuzione specifica di una procedura memorizzata, per vedere qual è il più parte costosa della procedura.


2
Non so perché query_hashsia 0, ma per quanto riguarda il motivo per cui le exec spSetUserAuth @userid;righe hanno diversi handle di piano: The algorithms to match new SQL statements to existing, unused execution plans in the cache require that all object references be fully qualified.( Origine .) Se tutte quelle voci fossero ad esempio exec dbo.spSetUserAuth @userid;, potresti ottenere identici handle di piano per loro.
Andriy M,

Hanno diversi plan_handle perché vengono utilizzati in database diversi, all'inizio non l'ho notato. In tal caso, i riferimenti agli oggetti non sono gli stessi, quindi i diversi piani. Grazie per averlo segnalato.
Bert Van Landeghem,

Se è così, non risolverebbe il tuo problema? È possibile generare report sulle attività per database e si potrebbero rilevare problemi di sniffing / parametrizzazione dei parametri con determinate procedure.
Tom V - prova topanswers.xyz il

Bene, sì in realtà ...
Bert Van Landeghem il

3
Se il tuo problema di fondo è stato effettivamente risolto, potresti pubblicare una risposta che spieghi i tuoi risultati e in che modo ciò ha contribuito a risolverlo? Non è necessario ma, se ciò può ispirarti in qualche modo, potrebbe essere un valido contributo alla base di conoscenza di questo sito. Tieni presente che preferiamo mantenere i commenti per tutto il tempo in cui aiutano a chiarire la domanda / risposta, quindi sentiti libero di ripetere tutti i punti già menzionati in questi commenti in modo che possano essere successivamente rimossi in modo sicuro.
Andriy M,

Risposte:


1

Per spiegare perché viene creato l'hash:

Quando inviamo una query al server, il processo algebrizer (sì, è così che viene chiamato) crea un hash, come una firma codificata, della query. L'hash è un identificatore univoco. Un identificatore è univoco per una determinata query, incluso tutto il testo che definisce la query, inclusi spazi e ritorni a capo, l'ottimizzatore confronta l'hash con le query nella cache. Se esiste una query nella cache che corrisponde alla query che entra nel motore, l'intero costo del processo di ottimizzazione viene ignorato e il piano di esecuzione nella cache del piano viene riutilizzato.

EXECavvia una procedura memorizzata che può avere la sua modifica del codice, poiché SQL Server sa che non è necessario confrontare EXECper ottimizzarlo, SQL Server non crea un hash.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.