首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MSSQL實時監控執行中SQL語句:自建存儲過程實現執行狀態可視化

     編輯:MySQL 資料庫相關知識

長時間運行的SQL語句(大報表、ETL、批次更新)常讓DBA「盲目等待」。本文提供一個生產可用的存儲過程dba_WhatSQLIsExecuting,可實時查看當前執行的SQL文本、會話資訊、等待類型、執行進度,助力慢查詢排查與進度條展示。

核心功能

  • 顯示當前正在執行的用戶會話(過濾系統SPID > 50)
  • 精確提取當前執行到的具體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;

進階應用:構建執行進度條

  1. 獲取start_time與當前時間差 → 已耗時
  2. 結合業務邏輯(如處理總行數、當前處理批次)估算總耗時
  3. 前端輪詢此存儲過程,繪製進度條

將此存儲過程部署到master庫,賦予監控賬號執行權限,即可構建輕量級SQL執行狀態儀表板。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved