Warum ist query_hash für EXEC-Anweisungen Null?


8

Ich richte ein Überwachungssystem für SQL Server mit erweiterten Ereignissen ein, um umfangreiche Abfragen als "Produktionsfeedback" für unsere Entwickler zu finden. Ich verwende die Ereignisse sp_statement_completedund sql_statement_completedmit Prädikatfiltern auf cpu_time, logischen Lesevorgängen usw. Ich hatte gehofft, die Ergebnisse auf database_nameund query_hashwie in zahlreichen Beispielen im gesamten Internet gezeigt zu aggregieren , aber in den Ergebnissen sehe ich, dass dies query_hashfür alle Anweisungen 0 ist Verwenden von EXEC wie in der folgenden Tabelle (Zeitstempel und Abfragehash zur besseren Lesbarkeit verkürzt).

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

Alle Ergebnisse haben einen Wert für plan_handleund sie sind alle unterschiedlich, so dass viele Pläne generiert werden. Andere Anweisungen ohne query_hash(die ich gesehen habe) umfassen ALTER INDEX, CHECKPOINT, UPDATE STATISTICS, COMMIT TRANSACTION, FETCH NEXT FROM Cursor, einige INSERTs, SELECT @variable, IF (@variable = x).

Weiß jemand warum das query_hash0 ist? Ich vermisse wahrscheinlich irgendwo den Punkt über SQL Query Analyzer und EXEC, aber ich kann keine Hinweise finden, die mich in die richtige Richtung weisen. Wenn die Ergebnisse, die ich habe, "normal" sind, wie kann man dann die Ergebnisse am besten aggregieren? Würde die Gruppierung nach Anweisung nicht Literale, Leerzeichen usw. enthalten, die bei der Berechnung von query_hash entfernt werden?

BEARBEITEN: Startet, wie ich es jetzt sehe EXEC SomeStoredProcedure, eine gespeicherte Prozedur (offensichtlich), und die einzelnen Anweisungen in dieser gespeicherten Prozedur landen in der Ereignissitzung als sp_statement_completedEreignisse, und alle haben einen query_hash.

Für sp_statement_completed(dh 'echte' Abfragen) kann ich also auf query_hash und database_name aggregieren, und für sql_statement_completedohne query_hash (EXEC SomeStoredProcedure) kann ich client_connection_iddie Anweisungen innerhalb einer bestimmten Ausführung einer gespeicherten Prozedur gruppieren, um zu sehen, was am meisten ist kostspieliger Teil des Verfahrens.


2
Ich weiß nicht, warum query_hash0 ist, aber warum exec spSetUserAuth @userid;Zeilen unterschiedliche Planhandles haben: The algorithms to match new SQL statements to existing, unused execution plans in the cache require that all object references be fully qualified.( Quelle .) Wenn alle diese Einträge zB exec dbo.spSetUserAuth @userid;wären, könnten Sie identische Planhandles für sie erhalten.
Andriy M

Sie haben unterschiedliche plan_handles, weil sie in unterschiedlichen Datenbanken verwendet werden. Das habe ich zunächst nicht bemerkt. In diesem Fall sind die Objektreferenzen nicht gleich, daher die verschiedenen Pläne. Vielen Dank für den Hinweis.
Bert Van Landeghem

Wenn das der Fall ist, würde das Ihr Problem nicht lösen? Sie könnten Berichte über Aktivitäten nach Datenbank erstellen und bei bestimmten Verfahren Probleme beim Aufspüren / Parametrisieren von Parametern erkennen.
Tom V - versuchen Sie topanswers.xyz

Nun ja, eigentlich ...
Bert Van Landeghem

3
Wenn Ihr zugrunde liegendes Problem tatsächlich gelöst wurde, können Sie eine Antwort veröffentlichen, in der Ihre Ergebnisse erläutert werden und wie dies zur Lösung des Problems beigetragen hat? Sie müssen nicht, aber wenn dies Sie in irgendeiner Weise inspirieren kann, könnte dies ein wertvoller Beitrag zur Wissensbasis dieser Site sein. Denken Sie daran, dass wir Kommentare lieber so lange aufbewahren, wie sie zur Klärung der Frage / Antwort beitragen. Sie können also alle in diesen Kommentaren bereits erwähnten Punkte wiederholen, damit sie später sicher entfernt werden können.
Andriy M

Antworten:


1

Um zu erklären, warum der Hash erstellt wird:

Wenn wir eine Abfrage an den Server senden, erstellt der Algebrizer-Prozess (ja, so wird er genannt) einen Hash wie eine codierte Signatur der Abfrage. Der Hash ist eine eindeutige Kennung. Ein Bezeichner ist für jede gegebene Abfrage eindeutig, einschließlich des gesamten Textes, der die Abfrage definiert, einschließlich Leerzeichen und Zeilenumbrüchen. Der Optimierer vergleicht den Hash mit Abfragen im Cache. Wenn im Cache eine Abfrage vorhanden ist, die mit der in die Engine eingehenden Abfrage übereinstimmt, werden die gesamten Kosten des Optimierungsprozesses übersprungen und der Ausführungsplan im Plan-Cache erneut verwendet.

EXECStartet eine gespeicherte Prozedur, deren Code geändert werden kann. Da SQL Server weiß, dass kein Vergleich erforderlich ist, um sie EXECzu optimieren, erstellt SQL Server keinen Hash.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.