web-dev-qa-db-fra.com

Comment vérifier les requêtes de blocage dans SQL Server

J'ai un serveur d'entrepôt qui a obtenu des données/synchronisation du système hérité 24/7, j'ai remarqué que la performance de certains de mes rapports/travaux sql est incertaine et la plupart du temps j'ai entendu de l'équipe DBA que mon la requête est bloquante = vers un autre processus de synchronisation.

De l'équipe DBA, j'ai découvert la commande, c'est-à-dire EXEC SP_WHO2, par laquelle je peux identifier le spid de la requête qui provoque le blocage en consultant la colonne BlkBy.

Veuillez me suggérer comment éviter le blocage et d'autres moyens de vérifier blocage dans SQL Server

7
user6498540

Outre Sp_Who2, vous pouvez utiliser la requête suivante pour identifier le blocage dans votre 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

Peut également vérifier les détails d'un SPID particulier à l'aide de la commande suivante.

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

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

This est un guide très complet. Quelques directives de base cependant:

  • Évitez le modèle SELECT ... INTO #temp Et créez d'abord un tableau et utilisez INSERT INTO #Temp SELECT...
  • Utilisez WITH (NOLOCK) sur les requêtes où vous pouvez tolérer lectures sales
  • Assurez-vous que index appropriés existent
  • Utilisez les prédicats sargable dans vos clauses WHERE
  • Discutez avec votre administrateur de base de données de la possibilité d'activer READ_COMMITTED_SNAPSHOT niveau d'isolement
4
Ben Campbell

Il existe une autre requête qui peut être utile. Cette requête vous fournira des détails importants sur l'ID de la session de blocage, l'heure (à partir de laquelle la session de blocage est en cours d'exécution), l'exécution de la requête, le compte d'utilisateur qui exécute cette session de blocage. La requête est très utile lorsque vous traitez avec un environnement de production avec de nombreux utilisateurs exécutant leurs transactions et que vous êtes censé découvrir la session de blocage et l'utilisateur et prendre les mesures nécessaires.

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
3