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_completed
und sql_statement_completed
mit Prädikatfiltern auf cpu_time, logischen Lesevorgängen usw. Ich hatte gehofft, die Ergebnisse auf database_name
und query_hash
wie in zahlreichen Beispielen im gesamten Internet gezeigt zu aggregieren , aber in den Ergebnissen sehe ich, dass dies query_hash
fü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_handle
und 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_hash
0 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_completed
Ereignisse, 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_completed
ohne query_hash (EXEC SomeStoredProcedure) kann ich client_connection_id
die Anweisungen innerhalb einer bestimmten Ausführung einer gespeicherten Prozedur gruppieren, um zu sehen, was am meisten ist kostspieliger Teil des Verfahrens.
quelle
query_hash
0 ist, aber warumexec 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 zBexec dbo.spSetUserAuth @userid;
wären, könnten Sie identische Planhandles für sie erhalten.Antworten:
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.
EXEC
Startet eine gespeicherte Prozedur, deren Code geändert werden kann. Da SQL Server weiß, dass kein Vergleich erforderlich ist, um sieEXEC
zu optimieren, erstellt SQL Server keinen Hash.quelle