J'essaie d'écrire une requête pour trouver des informations sur les statistiques de requête et le plan de requête pour une procédure stockée spécifique, mais je ne parviens pas à trouver la bonne DMV ou la requête pour rechercher une procédure stockée spécifique.
Jusqu'à présent j'ai:
select
qs.sql_handle
, qs.statement_start_offset
, qs.statement_end_offset
, qs.plan_handle
, execution_count
, st.text
, substring(st.text, (qs.statement_start_offset/2)+1,
((case qs.statement_end_offset
when -1
then datalength(st.text)
else
qs.statement_end_offset
end - qs.statement_start_offset) / 2 + 1)) as [Filtered text]
, qp.query_plan
from sys.dm_exec_query_stats as qs
cross apply sys.dm_exec_sql_text (qs.sql_handle) as st
cross apply sys.dm_exec_query_plan (qs.plan_handle) as qp
where st.text like '%myProcedure%'
order by qs.sql_handle
, execution_count desc
Mais cette requête ne renvoie aucune information. Idéalement, je remplacerais la condition st.text like
avec quelque chose comme object_name(procedure_id) = 'myProcedure'
, mais je ne trouve pas la bonne façon de le faire.
Y a-t-il une meilleure façon de le faire?
Je pourrais remplacer la condition dans la clause WHERE
avec un qs.sql_handle = 0x000004004040400..etc.
, mais comment puis-je découvrir le sql_handle
pour la procédure? (cette information n'est pas trouvée dans sys.objects
ou dans sys.procedures
).
Toute information est grandement appréciée.
Mise à jour :
J'ai exécuté la procédure (exec myProcedure ...
) dans un environnement de test et maintenant, il est renvoyé par la requête ci-dessus et je peux donc obtenir la poignée du plan pour utiliser le where sql_handle = 0x0034300..
, mais j'aimerais exécuter la même requête d'en haut en production, sans avoir à exécuter la procédure en production (juste pour connaître sa poignée de plan).
C'est la raison pour laquelle j'essaie d'écrire la requête de cette manière pour obtenir les informations basées sur le nom, pas sql_handle
(juste parce que dans le prod que je ne sais pas quel est son sql_handle
).
Étant donné que le DMV de sys.dm_exec_query_stats
renvoie des données pour l'ensemble de l'instance, vous devez être capable d'obtenir un schéma d'objet et des informations de nom dans toutes les bases de données. Utilisation de ST.objectid = OBJECT_ID(N'dbo.ProcedureName')
, comme cela a été suggéré, est sujettes à l'erreur car elle ne résoudra que le nom relatif à la base de données dans laquelle la requête est exécutée:
NULL
, qui fera filtrer toutes les lignes.object_id
__ que Peut-être Soyez correct, mais pourrait tout aussi bien). un objet différent et peut renvoyer une ou plusieurs lignes incorrectes.object_id
est renvoyée, si elle est correcte ou incorrecte, cette valeur particulière peut exister sur plusieurs bases de données et de récupérer plusieurs rangées pour différents objets dans différentes bases de données.À tout le moins, vous auriez besoin de fournir un nom d'objet entièrement qualifié (nommé à trois parties). Cependant, même si vous utilisez OBJECT_ID(N'DatabaseName.SchemaName.ObjectName')
, la requête a toujours le potentiel de résoudre le problème n ° 3 noté ci-dessus depuis que object_id
, même étant correct, peut exister sur plusieurs bases de données. Donc, vous avez besoin d'une seconde condition en utilisant la fonction DB_ID()
fonction pour réduire la base de données envisagée.
WHERE st.[objectid] = OBJECT_ID(N'DatabaseName.SchemaName.ObjectName')
AND st.[dbid] = DB_ID(N'DatabaseName')
Cependant, ma préférence est d'utiliser le Nom d'objet et Object_schema_name fonctions car ils acceptent tous les deux un 2ème paramètre optionnel pour database_id
. L'avantage ici est que vous pouvez les utiliser dans la clause SELECT
lorsque vous ne réduisez pas un objet spécifique, de sorte que vous puissiez voir les noms d'objet pour toutes les lignes du DMV. Il permet également de filtrer sur le même objet sur plusieurs bases de données, ce qui est utile lorsque vous avez la même procédure stockée dans plusieurs bases de données et que vous souhaitez voir des lignes pour elle dans toutes les bases de données, même s'il a probablement différentes valeurs de object_id
sur ces bases de données.
Par conséquent, vous pouvez éventuellement ajouter ce qui suit à la clause SELECT
(J'utilise cela lors de la croix appliquant sys.dm_exec_sql_text
sur DMVS tels que sys.dm_exec_requests
, etc.):
DB_NAME(st.[dbid]) AS [DatabaseName],
OBJECT_SCHEMA_NAME(st.[objectid], st.[dbid]) AS [SchemaName],
OBJECT_NAME(st.[objectid], st.[dbid]) AS [ObjectName]
Et vous mettriez ensuite à jour votre requête pour avoir la clause WHERE
suivante:
WHERE OBJECT_NAME(st.[objectid], st.[dbid]) = N'my_proc_name'
AND OBJECT_SCHEMA_NAME(st.[objectid], st.[dbid]) = N'dbo' -- or whatever schema
-- AND DB_NAME(st.[dbid]) = N'DatabaseName' -- optionally narrow down to specific DB
Essayez d'utiliser SYS_DM_EXEC_PROCEDURE_STATS
select object_name(object_id, database_id), * from sys.dm_exec_procedure_stats
where object_name(object_id, database_id) like '%proc name%'