623 字
3 分鐘
瀏覽次數
SQL 即時監看筆記:Profiler 與 Azure SQL XEvent
2026-04-24
2026-05-21

結論#

SQL Server 可直接用 SQL Server Profiler 即時監看 SQL,但 Azure SQL Database 不支援 Profiler,需要改用 Extended Events(XEvent)搭配 TSQL 查詢事件資料。

適合用在哪裡#

  • 查詢「誰正在打 SQL」
  • 分析 API / 系統即時 SQL
  • 排查慢查詢與高 CPU SQL
  • Azure SQL 無法使用 Profiler 時
  • DBA / 後端工程師效能分析

流程步驟#

1. 一般 SQL Server:直接使用 SQL Server Profiler#

  • SQL Server 傳統最常見做法

  • 可即時看到:

    • 執行中的 SQL
    • Duration
    • CPU
    • Login User
    • Application Name
  • 適合:

    • On-Prem SQL Server
    • VM SQL Server
    • 短時間即時除錯 操作位置:
  • SSMS → Tools → SQL Server Profiler image

常用事件:

  • RPC
  • SQL
  • SP 常用 Filter:
ApplicationName
LoginName
DatabaseName
Duration
TextData

實務上通常一定要加 Filter,不然大型系統會像瀑布一樣噴 SQL,眼睛直接工傷 (´-ω-`)

2. Azure SQL Database:改用 Extended Events(XEvent)#

  • Azure SQL Database 不支援 SQL Server Profiler
  • 官方也逐漸建議改用 XEvent
  • 效能比 Profiler 更好
  • 可自訂追蹤條件 建立 XEvent Session:
CREATE EVENTSESSION MonitorSQL
ON DATABASE
ADD EVENT sqlserver.sql_batch_completed(
ACTION (
sqlserver.client_app_name,
sqlserver.client_hostname,
sqlserver.username
)
)
ADD TARGET package0.ring_buffer;
GO

啟動 Session:

ALTER EVENTSESSION MonitorSQL
ON DATABASE
STATE=START;
GO

操作位置:

  • SSMS → XEvent 分析工具 → TSQL image

這邊使用:

  • sql_batch_completed
    • 監看 SQL 執行完成
  • ring_buffer
    • 暫存記憶體事件
    • 不需額外檔案權限 Azure SQL 很多環境沒有檔案系統權限,因此通常會優先用 ring_buffer。

3. 使用 TSQL 查詢即時 SQL 內容#

建立完成後,可直接查詢 XEvent 內容:

SELECT
event_data.value('(event/@name)[1]','varchar(50)')AS EventName,
event_data.value('(event/data[@name="duration"]/value)[1]','bigint')/1000AS DurationMs,
event_data.value('(event/action[@name="client_app_name"]/value)[1]','nvarchar(256)')AS AppName,
event_data.value('(event/action[@name="username"]/value)[1]','nvarchar(256)')AS UserName,
event_data.value('(event/data[@name="batch_text"]/value)[1]','nvarchar(max)')AS SQLText
FROM (
SELECTCAST(xet.target_dataAS XML)AS target_data
FROM sys.dm_xe_database_sessions s
JOIN sys.dm_xe_database_session_targets xet
ON s.address= xet.event_session_address
WHERE s.name='MonitorSQL'
) t
CROSS APPLY target_data.nodes('//RingBufferTarget/event')AS x(event_data);

可看到:

  • SQL 內容

  • 執行時間

  • 使用者

  • 呼叫 App

  • Host Name 對 API 系統非常好用,尤其查:

  • 哪支 API 打爆 DB

  • EF Core 產生什麼 SQL

  • 哪個排程在狂跑

補充#

  • Profiler 長時間開啟效能較差,不建議正式機長期使用
  • Azure SQL 建議搭配 Query Store 一起分析慢 SQL
  • XEvent 若沒停止,事件資料會持續累積

指令 / 範例整理#

Click to expand
-- 建立 XEvent
CREATE EVENTSESSION MonitorSQL
ON DATABASE
ADD EVENT sqlserver.sql_batch_completed(
ACTION (
sqlserver.client_app_name,
sqlserver.client_hostname,
sqlserver.username
)
)
ADD TARGET package0.ring_buffer;
GO
-- 啟動 XEvent
ALTER EVENTSESSION MonitorSQL
ON DATABASE
STATE=START;
GO
-- 查詢 XEvent
SELECT
event_data.value('(event/@name)[1]','varchar(50)')AS EventName,
event_data.value('(event/data[@name="duration"]/value)[1]','bigint')/1000AS DurationMs,
event_data.value('(event/action[@name="client_app_name"]/value)[1]','nvarchar(256)')AS AppName,
event_data.value('(event/action[@name="username"]/value)[1]','nvarchar(256)')AS UserName,
event_data.value('(event/data[@name="batch_text"]/value)[1]','nvarchar(max)')AS SQLText
FROM (
SELECTCAST(xet.target_dataAS XML)AS target_data
FROM sys.dm_xe_database_sessions s
JOIN sys.dm_xe_database_session_targets xet
ON s.address= xet.event_session_address
WHERE s.name='MonitorSQL'
) t
CROSS APPLY target_data.nodes('//RingBufferTarget/event')AS x(event_data);
-- 停止 XEvent
ALTER EVENTSESSION MonitorSQL
ON DATABASE
STATE= STOP;
GO
-- 刪除 XEvent
DROP EVENTSESSION MonitorSQLON DATABASE;
GO

收尾#

以前抓 SQL 靠 Profiler,現在 Azure SQL 時代,XEvent 幾乎已經是標配了。

會寫一份 XEvent TSQL,很多效能問題就不用靠運氣通靈。

SQL 即時監看筆記:Profiler 與 Azure SQL XEvent
https://joyceowo.github.io/posts/34ca78ea09fa8099a9d9c84c70d5b503/
作者
JoyceOwO
發佈於
2026-04-24
許可協議
CC BY-NC-SA 4.0