SQL Server Profiler 是圖形化追蹤與分析工具,支援監控查詢、收集效能資料、診斷死鎖、調試 T-SQL、重播負載。本文系統介紹 Profiler 核心概念 (追蹤、事件、資料行、篩選、模板)、自動化腳本化追蹤 (sp_trace_* 預存程序)、結合系統效能監視器分析、使用最佳實務 (降低負載) 以及無 Profiler 環境下使用 DMV (sys.dm_exec_query_stats) 快速定位效能問題。

點選 事件選擇 頁籤,勾選需捕捉的事件類別與事件。常用效能分析事件:
| 事件類別 | 事件 | 說明 |
|---|---|---|
| Stored Procedures | RPC:Completed | 遠程程序呼叫完成 (參數化執行,效能較好) |
| SP:StmtCompleted | 預存程序內單條陳述式完成 | |
| TSQL | SQL:BatchCompleted | T-SQL 批次完成 |
| SQL:StmtCompleted | 單條 T-SQL 陳述式完成 | |
| Locks | Deadlock / Deadlock Chain | 死鎖發生與鏈路 |
| Errors and Warnings | Missing Column Statistics / Sort Warning / Hash Warning | 查詢優化器缺乏統計資訊、排序/雜湊溢寫 tempdb |
| Performance | Showplan XML / Showplan XML Statistics Profile | 執行計畫 XML (高負載,**生產環境慎用**) |


每個事件的屬性欄位。常用欄位:
| 資料行 | 說明 |
|---|---|
| EventClass | 事件類型 |
| TextData | SQL 陳述式文字 |
| CPU | CPU 時間 (ms) |
| Reads | 邏輯讀取次數 |
| Writes | 邏輯寫入次數 |
| Duration | 執行持續時間 (ms) |
| SPID | 伺服器處理序 ID |
| StartTime / EndTime | 開始/結束時間 |
| DatabaseID / ObjectID / IndexID | 資料庫/物件/索引識別碼 |
可點擊 組織資料行 調整顯示順序與分組。

在捕捉階段即過濾,大幅降低負載與輸出量。常用篩選:
| 資料行 | 篩選條件範例 | 用途 |
|---|---|---|
| ApplicationName | NOT LIKE 'SQL Profiler' | 排除 Profiler 自身產生的事件 |
| DatabaseID | Equals 目標 DB_ID | 僅監控特定資料庫 |
| Duration | >= 2 (ms) | 忽略極短查詢,專注慢查詢 |
| Reads | >= 2 | 忽略低 IO 查詢 |
| SPID | Equals 特定 SPID | 鎖定特定連線 |




GUI 追蹤會透過網路回傳事件至用戶端緩衝區,造成伺服器額外負載。生產環境建議使用系統預存程序建立伺服器端追蹤:
sp_trace_create:建立追蹤定義,回傳 traceid。sp_trace_setevent:加入事件與資料行。sp_trace_setfilter:套用篩選條件。sp_trace_setstatus @traceid, 1:啟動追蹤 (背景運行,不需保持 SSMS 連線)。-- 查看所有作用中追蹤
SELECT * FROM ::fn_trace_getinfo(default);
-- 停止追蹤 (traceid=1)
EXEC sp_trace_setstatus 1, 0;
-- 關閉並移除定義
EXEC sp_trace_setstatus 1, 2;
產生的 .trc 檔案可用 Profiler 開啟分析,或用 fn_trace_gettable 讀入資料表查詢。
sqlcmd 執行。若同步擷取 PerfMon (.blg) 與 Profiler (.trc) 且時間範圍重疊:
可快速將「系統資源壓力點」對應到「具體高耗查詢」。
sys.dm_exec_query_stats 保存快取計畫的彙總執行統計,即時查詢無需追蹤:
-- 依總 CPU 時間找前 20 高耗查詢
SELECT TOP 20
qs.total_worker_time / qs.execution_count AS avg_cpu_ms,
qs.total_logical_reads / qs.execution_count AS avg_logical_reads,
qs.execution_count,
SUBSTRING(st.text, (qs.statement_start_offset/2)+1,
((CASE qs.statement_end_offset WHEN -1 THEN DATALENGTH(st.text)
ELSE qs.statement_end_offset END - qs.statement_start_offset)/2)+1) AS query_text,
qp.query_plan
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
ORDER BY qs.total_worker_time DESC;
常用欄位:
| 欄位 | 說明 |
|---|---|
| plan_handle | 執行計畫控制代碼 |
| creation_time | 計畫建立時間 |
| last_execution_time | 最後執行時間 |
| execution_count | 執行次數 |
| total_worker_time | 累積 CPU 時間 (微秒) |
| total_logical_reads/writes | 累積邏輯讀/寫 |
| query_hash / query_plan_hash | 識別相似邏輯/計畫的雜湊值 |
搭配 sys.dm_exec_sql_text、sys.dm_exec_query_plan 即可取得完整查詢文字與執行計畫。