Je suis en train de mettre en place un système de surveillance pour SQL Server en utilisant des événements étendus pour trouver des requêtes lourdes en tant que «retour de production» pour nos développeurs. J'utilise les événements sp_statement_completed
et sql_statement_completed
, avec des filtres de prédicat sur cpu_time, des lectures logiques, etc. J'espérais agréger les résultats database_name
et query_hash
comme démontré dans de nombreux exemples partout sur Internet, mais dans les résultats, je vois que query_hash
c'est 0 pour toutes les instructions en utilisant EXEC, comme dans le tableau ci-dessous (horodatage et queryhash raccourcis pour plus de lisibilité).
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
Tous les résultats ont une valeur pour plan_handle
et ils sont tous différents, donc beaucoup de plans sont générés. D'autres instructions sans query_hash
(que j'ai vues) incluent ALTER INDEX, CHECKPOINT, UPDATE STATISTICS, COMMIT TRANSACTION, FETCH NEXT FROM Cursor, certains INSERT, SELECT @variable, IF (@variable = x).
Est-ce que quelqu'un sait pourquoi le query_hash
est 0? Je manque probablement le point quelque part sur l'Analyseur de requêtes SQL et EXEC, mais je ne suis pas en mesure de trouver des indices pour me diriger dans la bonne direction. Si les résultats que j'obtiens sont «normaux», alors comment agréger au mieux les résultats? Le regroupement par instruction n'inclurait-il pas les littéraux, les espaces blancs, etc., qui sont supprimés lors du calcul de query_hash?
EDIT: comme je le vois maintenant, EXEC SomeStoredProcedure
démarre une procédure stockée (évidente), et les instructions individuelles dans cette procédure stockée se retrouvent dans la session d' sp_statement_completed
événement en tant qu'événements , et celles-ci ont toutes un query_hash.
Donc pour sp_statement_completed
(c'est-à-dire les «vraies» requêtes), je peux agréger sur query_hash et database_name, et pour sql_statement_completed
sans query_hash (EXEC SomeStoredProcedure), je peux utiliser le client_connection_id
pour regrouper les instructions dans une exécution spécifique d'une procédure stockée, pour voir ce qui est le plus partie coûteuse de la procédure.
query_hash
est 0 mais quant à la raison pour laquelle lesexec spSetUserAuth @userid;
lignes ont des poignées de plan différentes:The algorithms to match new SQL statements to existing, unused execution plans in the cache require that all object references be fully qualified.
( Source .) Si toutes ces entrées étaient par exempleexec dbo.spSetUserAuth @userid;
, vous pourriez obtenir des poignées de plan identiques pour elles.