特定のストアドプロシージャのクエリ統計とクエリプランに関する情報を検索するクエリを作成しようとしていますが、特定のストアドプロシージャを検索するための適切なDMVまたはクエリを見つけることができません。
これまでのところ:
_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
_
ただし、このクエリは情報を返しません。理想的には、_st.text like
_条件をobject_name(procedure_id) = 'myProcedure'
のようなものに置き換えますが、正しい方法を見つけることができません。
そうするためのより良い方法はありますか?
WHERE
句の条件を_qs.sql_handle = 0x000004004040400..etc.
_で置き換えることができますが、プロシージャの_sql_handle
_を見つけるにはどうすればよいですか? (この情報は_sys.objects
_または_sys.procedures
_にはありません)。
どんな情報でも大歓迎です。
更新:
プロシージャ(_exec myProcedure ...
_)をテスト環境で実行し、上記のクエリによって返されたので、プランハンドルを取得して_where sql_handle = 0x0034300..
_を使用できますが、実行したいと思います本番環境で上記の同じクエリを実行します(本番環境でプロシージャを実行する必要はありません(プランハンドルを見つけるため))。
これが、_sql_handle
_ではなく名前に基づいて情報を取得するためにこのようにクエリを記述しようとしている理由です(製品では、_sql_handle
_が何であるかわからないため) 。
_sys.dm_exec_query_stats
_ DMVがインスタンス全体のデータを返すとすると、すべてのデータベースにわたってオブジェクトスキーマと名前の情報を取得できる必要があります。推奨されているようにST.objectid = OBJECT_ID(N'dbo.ProcedureName')
を使用すると、クエリが実行されているデータベースに関連する名前のみが解決されるため、エラーが発生しやすくなります。
NULL
が返され、すべての行が除外されます。object_id
_値が得られます正しいしかし、別のオブジェクトを指すだけでなく、1つ以上の誤った行を返す可能性もあります。object_id
_値が返された場合、正しいか正しくないかにかかわらず、その特定の値は複数のデータベースに存在する可能性があるため、異なるデータベースの異なるオブジェクトに対して複数の行が返される可能性があります。少なくとも、完全修飾オブジェクト名(つまり、3部構成の名前)を提供する必要があります。ただし、OBJECT_ID(N'DatabaseName.SchemaName.ObjectName')
を使用した場合でも、_object_id
_が正しい場合でも複数のデータベースに存在する可能性があるため、クエリには上記の問題#3が発生する可能性があります。したがって、目的のデータベースに絞り込むためにDB_ID()
関数を使用する2番目の条件が必要です。
_WHERE st.[objectid] = OBJECT_ID(N'DatabaseName.SchemaName.ObjectName')
AND st.[dbid] = DB_ID(N'DatabaseName')
_
ただし、どちらも_database_id
_のオプションの2番目のパラメーターを受け入れるため、私の好みは OBJECT_NAME および OBJECT_SCHEMA_NAME 関数を使用することです。ここでの利点は、特定のオブジェクトに絞り込んでいないときにSELECT
句でそれらを使用できるため、DMVのすべての行のオブジェクト名を確認できることです。また、複数のデータベースにまたがる同じオブジェクトまでフィルタリングすることもできます。これは、複数のデータベースに同じストアドプロシージャがあり、異なる_object_id
_値が含まれている可能性がある場合でも、すべてのデータベースにその行を表示する場合に役立ちます。それらのデータベース全体。
したがって、オプションで以下をSELECT
句に追加できます(_sys.dm_exec_sql_text
_などのDMVに_sys.dm_exec_requests
_をクロス適用するときに使用します)。
_DB_NAME(st.[dbid]) AS [DatabaseName],
OBJECT_SCHEMA_NAME(st.[objectid], st.[dbid]) AS [SchemaName],
OBJECT_NAME(st.[objectid], st.[dbid]) AS [ObjectName]
_
次に、次のWHERE
句を含むようにクエリを更新します。
_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
_
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%'