SQL Server Performance Tuning

Mastering the Art of Resolving Blocking

Understanding and Resolving Blocking in SQL Server

Blocking occurs when one session holds a lock on a database object, and another session needs to acquire a conflicting lock on the same object. This tutorial explores the causes, identification, and resolution strategies for SQL Server blocking.

What is Blocking?

SQL Server uses locking to ensure data consistency during concurrent operations. When a transaction modifies data, it acquires locks. If another transaction attempts to perform an operation that conflicts with an existing lock (e.g., reading data that is being updated), it must wait. The session that is waiting for the lock to be released is "blocked" by the session holding the lock.

Common Causes of Blocking

Identifying Blocking

Several tools and techniques can help identify blocking:

Using SQL Server Management Studio (SSMS) Activity Monitor

SSMS provides a graphical interface to monitor processes. Navigate to Management > Activity Monitor. In the "Processes" pane, you can see blocked processes indicated by a value greater than 0 in the "Blocked By" column.

Using Dynamic Management Views (DMVs)

DMVs offer detailed insights into SQL Server's internal state. The following query is a common way to identify blocking:


SELECT
    session_id,
    wait_type,
    wait_time,
    blocking_session_id,
    resource_description
FROM
    sys.dm_exec_requests
WHERE
    blocking_session_id <> 0;
            

To get more detailed information about the blocking session and the blocked session:


SELECT
    T1.resource_type,
    T1.resource_database_name,
    T1.request_mode,
    T1.request_status,
    T2.session_id AS waiting_session_id,
    T2.program_name,
    T2.login_name,
    T2.host_name,
    T3.session_id AS blocking_session_id,
    T3.program_name AS blocking_program_name,
    T3.login_name AS blocking_login_name,
    T3.host_name AS blocking_host_name,
    SUBSTRING(T4.text, T2.statement_start_offset/2 + 1,
        (CASE WHEN T2.statement_end_offset = -1
            THEN LEN(CAST(T4.text AS NVARCHAR(MAX))) * 2
            ELSE T2.statement_end_offset
        END - T2.statement_start_offset)/2) AS blocked_statement,
    SUBSTRING(T5.text, T3.statement_start_offset/2 + 1,
        (CASE WHEN T3.statement_end_offset = -1
            THEN LEN(CAST(T5.text AS NVARCHAR(MAX))) * 2
            ELSE T3.statement_end_offset
        END - T3.statement_start_offset)/2) AS blocking_statement
FROM
    sys.dm_tran_locks AS T1
JOIN
    sys.dm_exec_requests AS T2 ON T1.lock_owner_address = T2.lock_owner_address
JOIN
    sys.dm_exec_requests AS T3 ON T2.blocking_session_id = T3.session_id
CROSS APPLY
    sys.dm_exec_sql_text(T2.sql_handle) AS T4
CROSS APPLY
    sys.dm_exec_sql_text(T3.sql_handle) AS T5
WHERE
    T2.session_id <> T3.session_id;
            

Resolving Blocking Issues

1. Optimize Queries

Inefficient queries are a primary cause of blocking. Analyze execution plans, add appropriate indexes, and rewrite queries to be more efficient.

Tip: Ensure that `WHERE` clauses in your queries are SARGable (Search ARGument-able) to allow SQL Server to use indexes effectively.

2. Shorten Transaction Durations

Keep transactions as short as possible. Commit or rollback transactions promptly. Avoid user interaction or long processing steps within a transaction.

3. Review Transaction Isolation Levels

Understand the implications of different isolation levels (e.g., READ COMMITTED, REPEATABLE READ, SERIALIZABLE). The default `READ COMMITTED` is often suitable, but consider `READ COMMITTED SNAPSHOT ISOLATION` (RCSI) for reduced blocking if appropriate for your application.

4. Manage Application Logic

Ensure your application code handles transactions correctly, avoids holding locks unnecessarily, and implements retry logic for transient blocking scenarios.

5. Kill Blocking Sessions (Use with Caution)

In critical situations, you might need to terminate a blocking session. This should be a last resort, as it can lead to data rollback for the killed session.


-- Replace  with the actual blocking_session_id
KILL ;
            
Caution: Killing a session can cause data loss or corruption if not handled carefully. Always understand the impact before proceeding.

6. Deadlock Resolution

Deadlocks are a special case of blocking. SQL Server automatically detects and resolves deadlocks by choosing a "victim" session to rollback. Monitor for deadlock events using SQL Server Profiler or Extended Events and analyze the deadlock graphs to identify the cause.

Best Practices for Prevention