仕事でパフォーマンスの問題が発生しているため、SQL Server の動的管理ビューについて詳しく学んでいます。おそらく、これは物事の見方が間違っているのですが、利用可能なツールは ... 私が望むほど柔軟ではないようです。
私が例を持っている次のようなことを見つけられるようにしたいと思います。
通常よりも 20% 以上遅く実行されているクエリはどれですか? 下 ...
--displays regarding about procedures that are currently taking longer to execute by more than 20% over the average.
;
with data as (
select s.plan_handle
, db.name
, ObjectName = OBJECT_NAME(t.objectid, t.dbid )
, PlanCompileDate = s.creation_time
, PlanExecutionCount = execution_count
, AvgElapsedSeconds = ( total_elapsed_time/ CAST( 1000000 as float(15) ) ) / CAST( s.execution_count as float(15) )
, LastElapsedSeconds = last_elapsed_time / CAST( 1000000 as float(38) )
, LeastElapsedSeconds = min_elapsed_time / CAST( 1000000 as float(15) )
, MostElapsedSeconds = max_elapsed_time / CAST( 1000000 as float(15) )
, LastExecPercentageDevTime = (( ( s.total_elapsed_time / cast(s.execution_count as float(15) ) ) - s.last_elapsed_time ) / ( case s.last_elapsed_time when 0 then -1.00 else ( s.total_elapsed_time / cast( s.execution_count as float(15) ) ) end ) ) * -100
-- 0.00532225
, AvgRowsReturned = total_rows / CAST( s.execution_count as float )
, LastRowsReturned = last_rows
, LeastRowsReturned = min_rows
, MostRowsReturned = max_rows
, LastExecPercentageDevRows = (( ( s.total_rows / cast(s.execution_count as float ) ) - s.last_rows) / ( case s.last_rows when 0 then -1.00 else ( s.total_rows / cast( s.execution_count as float ) ) end ) ) * -100
, AvgCPUTime = s.total_worker_time / CAST( s.execution_count as float )
, LastCPUTime = s.last_worker_time
, LeastCPUTime = min_worker_time
, MostCPUTime = max_worker_time
, LastExecPercentageDevCPUTime = (( ( s.total_worker_time / cast(s.execution_count as float ) ) - s.last_worker_time ) / ( case s.last_worker_time when 0 then -1.00 else ( s.total_worker_time / cast( s.execution_count as float ) ) end ) ) * -100
, AvgPhysicalReads = s.total_physical_reads / CAST( s.execution_count as float )
, LastPhysicalReads = s.last_physical_reads
, LeastPhysicalReads = s.min_physical_reads
, MostPhysicalReads = s.max_physical_reads
, LastExecPercentageDevPhysicalReads = (( ( s.total_physical_reads / cast(s.execution_count as float ) ) - s.last_physical_reads ) / ( case s.last_physical_reads when 0 then -1.00 else ( s.total_physical_reads / cast( s.execution_count as float ) ) end ) ) * -100
, AvgLogicalReads = s.total_logical_reads / CAST( s.execution_count as float )
, LastLogicalReads = s.last_logical_reads
, LeastLogicalReads = s.min_logical_reads
, MostLogicalReads = s.max_logical_reads
, LastExecPercentageDevLogicalReads = (( ( s.total_logical_reads / cast(s.execution_count as float ) ) - s.last_logical_reads ) / ( case s.last_logical_reads when 0 then -1.00 else ( s.total_logical_reads / cast( s.execution_count as float ) ) end ) ) * -100
, AvgLogicalWrites = s.total_logical_Writes / CAST( s.execution_count as float )
, LastLogicalWrites = s.last_logical_Writes
, LeastLogicalWrites = s.min_logical_Writes
, MostLogicalWrites = s.max_logical_Writes
, LastExecPercentageDevLogicalWrites = (( ( s.total_logical_writes / cast(s.execution_count as float ) ) - s.last_logical_writes ) / ( case s.last_logical_writes when 0 then -1.00 else ( s.total_logical_writes / cast( s.execution_count as float ) ) end ) ) * -100
, t.text
, t.number
, t.objectid
, s.query_hash
--, s.*
FROM sys.dm_exec_query_stats AS s
CROSS APPLY sys.dm_exec_sql_text(s.sql_handle) AS t
LEFT JOIN sys.databases AS DB
ON t.dbid = DB.database_id
)
select *
from data
where LastExecPercentageDevTime > 20 and -- changed by at least 20%
PlanExecutionCount > 10 and -- executed more than 10 times
LastElapsedSeconds != 0 -- we don't care about queries that executed quickly
order by LastExecPercentageDevTime desc
ブロッキングがある場合、ブロッキングを行っているクエリと、おそらくその依存オブジェクトは何かを判断できるようにしたいと考えています。
次の方法で、ブロッキングを行っているクエリを見つけることができると思います
-- What queries are the source of all the blocking.
with blockingSessions as(
select session_id,blocking_session_id
from sys.dm_exec_requests
where blocking_session_id > 0
), causal as(
select blocking_session_id
from blockingSessions
where blocking_session_id not in(select session_id from blockingSessions)
)--select * from causal
select t.text
,SPID = con.most_recent_session_id
,STATUS = s.STATUS
,[Login] = s.login_name
,Host = s.host_name
--,BlkBy = r.blocking_session_id
,DBName = d.name
,CommandType = r.command
,SQLStatement = t.text
,ObjectName = OBJECT_NAME(t.objectid)
,ElapsedMS = r.total_elapsed_time
,CPUTime = r.cpu_time
,IOReads = r.logical_reads + r.reads
,IOWrites = r.writes
,LastWaitType = r.last_wait_type
,StartTime = r.start_time
,Protocol = con.net_transport
,ConnectionWrites = con.num_writes
,ConnectionReads = con.num_reads
,ClientAddress = con.client_net_address
,Authentication = con.auth_scheme
--,t.*
from causal c
join sys.dm_exec_connections con
on c.blocking_session_id = con.session_id
join sys.dm_exec_sessions s
on con.most_recent_session_id = s.session_id
left join sys.dm_exec_requests r
on s.session_id = r.session_id
outer APPLY sys.dm_exec_sql_text(con.most_recent_sql_handle) AS t
left join sys.databases d
on t.dbid = d.database_id
しかし、私は以下を達成する方法を理解することができませんでした...
特定のクエリが今日 (前回のプランのコンパイル時以降ではなく) 何回実行されたか? 今日、特定のストアド プロシージャが何回実行されたか? 特定のパラメーターで何回呼び出されましたか?
たぶん、皆さんが考えることができる有用な他のいくつかのものがあり、皆さんは私が上に挙げたものにいくつかの提案を提供できるかもしれません. 私が把握できていないもう 1 つのことは、動的管理ビューで接続、要求、およびセッションの間の関係が正確に何であるかということです。
編集
x時間とy時間の間に起こったことのように、特定の期間にビューを使用しようとしていると思います。しかし、それらはそのために設計されているようには見えません。これは正しいです?SQLサーバーから期間ごとに同様の情報を取得する別の方法はありますか?