SQL Serverの負荷が高かったりで、そのときに実行されているクエリを抽出する方法
実行中のクエリを抽出
今実行されているクエリを抽出するときは、こちらを実行すると、実行されているクエリが抽出される
SELECT sqltext.TEXT,
req.session_id,
req.status,
req.command,
req.cpu_time,
req.total_elapsed_time
FROM sys.dm_exec_requests req
CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS sqltext
長時間実行されているクエリを消すときは、上記結果で抽出されたsession_idに対しKILLを行う
KILL [session_id]
ロック状況を確認
Delete文や、Update文を流そうとしたけれど、なかなか実行完了しないときは、テーブルに対して、レコードに対してロックが掛かっている可能性がある。そのときに、このクエリを実行するとロック状況が確認できる
SELECT
resource_type AS type
,resource_associated_entity_id as entity_id
,( CASE WHEN resource_type = 'OBJECT' THEN
OBJECT_NAME( resource_associated_entity_id )
ELSE
( SELECT
OBJECT_NAME( OBJECT_ID )
FROM
sys.partitions
WHERE
hobt_id=resource_associated_entity_id )
END)
AS object_name -- ここにテーブル名が表示される
,request_mode AS request_mode
,request_type AS request_type
,request_status AS request_status
,request_session_id AS session_id
FROM
sys.dm_tran_locks
WHERE
resource_type <> 'DATABASE'
ORDER BY
request_session_id
「object_name」にロックが掛かっているテーブル名が出力されるので、Update/Deleteしたいテーブルが該当の場合、まずはロックを解除する必要がある可能性
これも最後のsession_idを指定することで、KILLしクエリの実行を止めることができる。
Session IDからクエリを特定する
例えば、sp_who2などのStored Procedureを実行すると、どのプロセスがどのプロセスをSuspendの状態にしている(要は待たせている)かを出力することができる。が、どのプロセスかは特定できても、その実行中のクエリは見ることができない。
そのときに、このクエリを実行する。
Session IDをKeyにそのクエリを抽出する。
DECLARE @sqltext VARBINARY(128)
SELECT @sqltext = sql_handle
FROM sys.sysprocesses
WHERE spid = 【Session ID】--ここを置き換え
SELECT TEXT
FROM sys.dm_exec_sql_text(@sqltext)
GO