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_completedet 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_nameet query_hashcomme démontré dans de nombreux exemples partout sur Internet, mais dans les résultats, je vois que query_hashc'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_handleet 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_hashest 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 SomeStoredProceduredé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_completedsans query_hash (EXEC SomeStoredProcedure), je peux utiliser le client_connection_idpour 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_hashest 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.