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.
la source
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.Réponses:
Pour expliquer pourquoi le hachage est créé:
Lorsque nous soumettons une requête au serveur, le processus algébrizer (oui c'est comme ça qu'on l'appelle) crée un hachage, comme une signature codée, de la requête. Le hachage est un identifiant unique. Un identifiant est unique pour toute requête donnée, y compris tout le texte qui définit la requête, y compris les espaces et les retours chariot, l'optimiseur compare le hachage aux requêtes dans le cache. Si une requête existe dans le cache qui correspond à la requête entrant dans le moteur, le coût total du processus d'optimisation est ignoré et le plan d'exécution dans le cache du plan est réutilisé.
EXEC
démarre une procédure stockée qui peut voir son code changer, car SQL Server sait qu'il n'a pas besoin de comparerEXEC
pour l'optimiser, SQL Server ne crée pas de hachage.la source