web-dev-qa-db-ja.com

SQL Serverでブロッキングクエリを確認する方法

レガシーシステムから24時間年中無休でデータ/同期を取得するウェアハウスサーバーが1つあり、レポート/ SQLジョブのパフォーマンスの一部が不確かであり、ほとんどの場合、DBAチームから私のクエリがブロックされている =他の同期プロセスへ。

DBAチームからコマンドを知りました。つまり、EXEC SP_WHO2を使用して、列BlkByを調べることで、ブロッキングを引き起こすクエリのspidを特定できます。

ブロックを回避する方法と他のチェック方法ブロッキングSQL Serverを教えてください

7
user6498540

Sp_Who2とは別に、次のクエリを使用してSQLのブロッキングを特定できます。

SELECT
db.name DBName,
tl.request_session_id,
wt.blocking_session_id,
OBJECT_NAME(p.OBJECT_ID) BlockedObjectName,
tl.resource_type,
h1.TEXT AS RequestingText,
h2.TEXT AS BlockingTest,
tl.request_mode
FROM sys.dm_tran_locks AS tl
INNER JOIN sys.databases db ON db.database_id = tl.resource_database_id
INNER JOIN sys.dm_os_waiting_tasks AS wt ON tl.lock_owner_address = wt.resource_address
INNER JOIN sys.partitions AS p ON p.hobt_id = tl.resource_associated_entity_id
INNER JOIN sys.dm_exec_connections ec1 ON ec1.session_id = tl.request_session_id
INNER JOIN sys.dm_exec_connections ec2 ON ec2.session_id = wt.blocking_session_id
CROSS APPLY sys.dm_exec_sql_text(ec1.most_recent_sql_handle) AS h1
CROSS APPLY sys.dm_exec_sql_text(ec2.most_recent_sql_handle) AS h2
GO

また、次のコマンドを使用して特定のSPIDの詳細を確認できます。

DBCC INPUTBUFFER(56) — Will give you the Event Info.

KILL 56 -- Will kill the session of this id.

これ は非常に包括的なガイドです。ただし、いくつかの基本的なガイドライン:

  • _SELECT ... INTO #temp_パターンを避け、代わりに最初にテーブルを作成して_INSERT INTO #Temp SELECT..._を使用する
  • 許容できるクエリでWITH (NOLOCK)を使用 ダーティリード
  • 適切なインデックス が存在することを確認します
  • WHERE句で sargable 述語を使用する
  • 潜在的に有効にする _READ_COMMITTED_SNAPSHOT_ 分離レベルについてDBAに相談してください
4
Ben Campbell

便利な別のクエリがあります。このクエリは、ブロッキングセッションID、時間(ブロッキングセッションが実行されているときから)、クエリの実行、このブロッキングセッションを実行しているユーザーアカウントに関する重要な詳細を提供します。このクエリは、トランザクションを実行している多くのユーザーがいる実稼働環境を扱っており、ブロッキングセッションとユーザーを見つけて、必要なアクションを実行する場合に非常に役立ちます。

SELECT
[s_tst].[session_id],
[s_es].[login_name] AS [Login Name],
DB_NAME (s_tdt.database_id) AS [Database],
[s_tdt].[database_transaction_begin_time] AS [Begin Time],
[s_tdt].[database_transaction_log_bytes_used] AS [Log Bytes],
[s_tdt].[database_transaction_log_bytes_reserved] AS [Log Rsvd],
[s_est].text AS [Last T-SQL Text],
[s_eqp].[query_plan] AS [Last Plan]
FROM
sys.dm_tran_database_transactions [s_tdt]
JOIN
sys.dm_tran_session_transactions [s_tst]
ON
[s_tst].[transaction_id] = [s_tdt].[transaction_id]
JOIN
sys.[dm_exec_sessions] [s_es]
ON
[s_es].[session_id] = [s_tst].[session_id]
JOIN
sys.dm_exec_connections [s_ec]
ON
[s_ec].[session_id] = [s_tst].[session_id]
LEFT OUTER JOIN
sys.dm_exec_requests [s_er]
ON
[s_er].[session_id] = [s_tst].[session_id]
CROSS APPLY
sys.dm_exec_sql_text ([s_ec].[most_recent_sql_handle]) AS [s_est]
OUTER APPLY
sys.dm_exec_query_plan ([s_er].[plan_handle]) AS [s_eqp]
ORDER BY
[Begin Time] ASC;
GO