623 字
3 分鐘
SQL 即時監看筆記:Profiler 與 Azure SQL XEvent
結論
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

常用事件:
- RPC
- SQL
- SP
常用 Filter:
ApplicationNameLoginNameDatabaseNameDurationTextData實務上通常一定要加 Filter,不然大型系統會像瀑布一樣噴 SQL,眼睛直接工傷 (´-ω-`)
2. Azure SQL Database:改用 Extended Events(XEvent)
- Azure SQL Database 不支援 SQL Server Profiler
- 官方也逐漸建議改用 XEvent
- 效能比 Profiler 更好
- 可自訂追蹤條件 建立 XEvent Session:
CREATE EVENTSESSION MonitorSQLON DATABASEADD EVENT sqlserver.sql_batch_completed(ACTION ( sqlserver.client_app_name, sqlserver.client_hostname, sqlserver.username ))ADD TARGET package0.ring_buffer;GO啟動 Session:
ALTER EVENTSESSION MonitorSQLON DATABASESTATE=START;GO操作位置:
- SSMS → XEvent 分析工具 → TSQL

這邊使用:
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 SQLTextFROM (SELECTCAST(xet.target_dataAS XML)AS target_dataFROM sys.dm_xe_database_sessions sJOIN sys.dm_xe_database_session_targets xetON s.address= xet.event_session_addressWHERE s.name='MonitorSQL') tCROSS 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
-- 建立 XEventCREATE EVENTSESSION MonitorSQLON DATABASEADD EVENT sqlserver.sql_batch_completed(ACTION ( sqlserver.client_app_name, sqlserver.client_hostname, sqlserver.username ))ADD TARGET package0.ring_buffer;GO
-- 啟動 XEventALTER EVENTSESSION MonitorSQLON DATABASESTATE=START;GO
-- 查詢 XEventSELECT 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 SQLTextFROM (SELECTCAST(xet.target_dataAS XML)AS target_dataFROM sys.dm_xe_database_sessions sJOIN sys.dm_xe_database_session_targets xetON s.address= xet.event_session_addressWHERE s.name='MonitorSQL') tCROSS APPLY target_data.nodes('//RingBufferTarget/event')AS x(event_data);
-- 停止 XEventALTER EVENTSESSION MonitorSQLON DATABASESTATE= STOP;GO
-- 刪除 XEventDROP EVENTSESSION MonitorSQLON DATABASE;GO收尾
以前抓 SQL 靠 Profiler,現在 Azure SQL 時代,XEvent 幾乎已經是標配了。
會寫一份 XEvent TSQL,很多效能問題就不用靠運氣通靈。
SQL 即時監看筆記:Profiler 與 Azure SQL XEvent
https://joyceowo.github.io/posts/34ca78ea09fa8099a9d9c84c70d5b503/