Skip to main content

查詢執行中 Session 與執行計畫的 SQL

查詢執行中 Session 與執行計畫的 SQL

本篇整理在 SQL Server 上查看「目前正在執行的查詢」常用的幾組 DMV 語法,可用於排查長時間執行、卡住或佔用資源的 session。

需要 VIEW SERVER STATE 權限才能查詢這些動態管理檢視(DMV)。

常用 DMV 與函式說明

  • sys.dm_exec_sessions:所有連線 session 的資訊(登入帳號、主機、程式等)。
  • sys.dm_exec_requests:目前正在執行的請求(狀態、開始時間、command 等)。
  • sys.dm_exec_sql_text(sql_handle):取得 SQL 文字。
  • sys.dm_exec_query_plan(plan_handle):取得執行計畫(XML),可看 Parameter List。

1. 查詢使用者連線的執行中請求(含 SQL 文字與執行計畫)

列出所有使用者 session 正在執行的請求,並依執行時間由長到短排序。

SELECT
    s.session_id,
    s.login_name,
    r.status,
    r.start_time,
    CONVERT(varchar(8), DATEADD(SECOND,
        DATEDIFF(SECOND, r.start_time, GETDATE()), '00:00:00'), 108) AS running_time_hhmmss,
    DB_NAME(r.database_id) AS database_name,
    r.command,
    st.text AS sql_text,
    qp.query_plan
FROM sys.dm_exec_sessions s
JOIN sys.dm_exec_requests r
    ON s.session_id = r.session_id
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) st
OUTER APPLY sys.dm_exec_query_plan(r.plan_handle) qp
WHERE s.is_user_process = 1   -- 過濾掉系統 session
ORDER BY running_time_hhmmss DESC;

2. 查詢目前正在執行的語句(含完整批次)

利用 statement_start_offset / statement_end_offset 取出「批次中目前正在執行的那一句」,同時保留完整批次方便對照。

SELECT
    r.session_id,
    r.status,
    r.start_time,
    CONVERT(varchar(8), DATEADD(SECOND,
        DATEDIFF(SECOND, r.start_time, GETDATE()), '00:00:00'), 108) AS running_time_hhmmss,
    SUBSTRING(st.text, r.statement_start_offset/2,
        (CASE WHEN r.statement_end_offset = -1
              THEN LEN(CONVERT(nvarchar(max), st.text)) * 2
              ELSE r.statement_end_offset END - r.statement_start_offset) /2) AS running_statement,
    st.text AS full_batch
FROM sys.dm_exec_requests r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) st
ORDER BY running_time_hhmmss DESC;

3. 查 sys.dm_exec_query_plan → 看執行計畫裡的 Parameter List(最常用)

針對特定 session_id 撈出 SQL 文字與執行計畫,常用來檢視執行計畫中的 Parameter List(參數編譯值),排查參數探測(parameter sniffing)問題。

SELECT
    r.session_id,
    st.text AS sql_text,
    qp.query_plan
FROM sys.dm_exec_requests r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) st
OUTER APPLY sys.dm_exec_query_plan(r.plan_handle) qp
WHERE r.session_id = '<你的 session_id>';

小提醒

  • running_time_hhmmss 以 hh:mm:ss 顯示執行時間,超過 24 小時會顯示不正確,長時間查詢建議改用秒數或 DATEDIFF 的天/時拆解。
  • query_plan 點開即為 XML 執行計畫,在 SSMS 中可直接點擊以圖形化檢視。
  • 找到問題 session 後,若要中止可使用 KILL <session_id>;(請小心使用)。