長時間運行的SQL語句(大報表、ETL、批次更新)常讓DBA「盲目等待」。本文提供一個生產可用的存儲過程dba_WhatSQLIsExecuting,可實時查看當前執行的SQL文本、會話資訊、等待類型、執行進度,助力慢查詢排查與進度條展示。
start_time與業務預估總量計算進度USE [RMA_DWH]
GO
SET ANSI_NULLS ON; SET QUOTED_IDENTIFIER ON;
GO
CREATE PROC [dbo].[dba_WhatSQLIsExecuting]
AS
BEGIN
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; -- 無鎖讀取,不阻塞業務
SELECT
[Spid] = session_id,
ecid,
[Database] = DB_NAME(sp.dbid),
[User] = nt_username,
[Status] = er.status,
[Wait] = wait_type,
[Individual Query] = SUBSTRING(qt.text,
er.statement_start_offset/2,
(CASE WHEN er.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE er.statement_end_offset END - er.statement_start_offset)/2),
[Parent Query] = qt.text,
Program = program_name,
Hostname,
nt_domain,
start_time
FROM sys.dm_exec_requests er
INNER JOIN sys.sysprocesses sp ON er.session_id = sp.spid
CROSS APPLY sys.dm_exec_sql_text(er.sql_handle) AS qt
WHERE session_id > 50 -- 忽略系統進程
AND session_id NOT IN (@@SPID) -- 忽略自身
ORDER BY 1, 2;
END
GO
| 技術 | 作用 |
|---|---|
READ UNCOMMITTED | 髒讀級別,避免監控查詢被業務鎖阻塞,亦不持有鎖 |
sys.dm_exec_requests | 核心DMV,返回每個請求的執行狀態、偏移量、等待資訊 |
CROSS APPLY dm_exec_sql_text | 根據sql_handle解析完整SQL文本 |
statement_start/end_offset | 以字節為單位定位「當前語句」在批次中的位置,/2轉為字符數 |
ecid | 並行執行時的子執行緒ID,0為主執行緒 |
-- 直接執行
EXEC [dbo].[dba_WhatSQLIsExecuting];
-- 遠程執行
EXEC YourServer.master.dbo.dba_WhatSQLIsExecuting;
start_time與當前時間差 → 已耗時將此存儲過程部署到master庫,賦予監控賬號執行權限,即可構建輕量級SQL執行狀態儀表板。