Queries to see rapidly what your SQL Server is doing NOW

When troubleshooting performance issues on a SQL Server instance, the first step is always to understand what is happening right now: which queries are running, which sessions are blocking others, and where time is being spent waiting. These three T-SQL scripts give you an immediate picture of the current workload using Dynamic Management Views (DMVs).

1. Blocked and Blocking Queries

If this query returns no rows, there are no blocked queries at this moment. Run it multiple times to catch short-lived blocking chains. Note: this surfaces current blocking only — cumulative short-term locking contention requires wait stats analysis (see section 2).

SELECT 'BLOCKING STATUS' AS Controllo,
    BlockedSPID     = LEFT(blocked.session_id, 5),
    BlockedQuery    = CONVERT(VARCHAR(50), blockedsql.text),
    BlockingSPID    = CONVERT(VARCHAR(50), blocking.session_id),
    BlockingQuery   = CONVERT(VARCHAR(50), blockingsql.text)
FROM sys.dm_exec_requests blocked
JOIN sys.dm_exec_requests blocking
    ON blocked.blocking_session_id = blocking.session_id
CROSS APPLY (SELECT * FROM sys.dm_exec_sql_text(blocked.sql_handle))  blockedsql
CROSS APPLY (SELECT * FROM sys.dm_exec_sql_text(blocking.sql_handle)) blockingsql;

2. Wait Event Analysis

SQL Server continuously collects wait statistics in sys.dm_os_wait_stats since the last instance restart. Resetting this view and collecting data for a short window gives you a focused picture of what the instance is spending time waiting on — I/O, CPU, locks, latches, and more. For a full reference of wait event types, see the MSDN documentation. The script below is based on Paul Randal’s well-known wait analysis methodology.

DBCC SQLPERF ('sys.dm_os_wait_stats', CLEAR); -- Reset the DMV
GO

SELECT
    [owt].[session_id],
    [owt].[exec_context_id],
    [owt].[wait_duration_ms],
    [owt].[wait_type],
    [owt].[blocking_session_id],
    [owt].[resource_description],
    [es].[program_name],
    [est].[text],
    [est].[dbid],
    [eqp].[query_plan],
    [es].[cpu_time],
    [es].[memory_usage]
FROM sys.dm_os_waiting_tasks [owt]
INNER JOIN sys.dm_exec_sessions  [es]  ON [owt].[session_id] = [es].[session_id]
INNER JOIN sys.dm_exec_requests  [er]  ON [es].[session_id]  = [er].[session_id]
OUTER APPLY sys.dm_exec_sql_text   ([er].[sql_handle])   [est]
OUTER APPLY sys.dm_exec_query_plan ([er].[plan_handle])  [eqp]
WHERE [es].[is_user_process] = 1
ORDER BY [owt].[session_id], [owt].[exec_context_id];

3. Open Transactions with Query Text and Execution Plan

sp_who2 and sys.dm_exec_requests show current sessions, but they don’t easily expose the full query text and execution plan for each open transaction. This script — also from Paul Randal’s SQLskills collection — joins the transaction DMVs to retrieve exactly that, including log usage per transaction. It’s particularly useful for diagnosing long-running transactions that are holding locks or consuming transaction log space.

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_record_count]   AS [Log Records],
    s_tdt.[database_transaction_log_bytes_used]     AS [Log Bytes],
    s_tdt.[database_transaction_log_bytes_reserved] AS [Log Reserved],
    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 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;