首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 查詢效能測量三板斧:STATISTICS TIME、IO、PROFILE 實戰用法

     編輯:關於SqlServer

核心指令組合


-- 開啟統計
SET STATISTICS TIME ON;   -- 解析/編譯/執行 CPU 時間、經過時間
SET STATISTICS IO ON;     -- 邏輯讀/物理讀/預讀/LOB 讀 (最關鍵指標)
SET STATISTICS PROFILE ON; -- 執行計畫文字版 (含估算/實際行數、運算子、成本) -- 注意:2016+ 建議用 SET STATISTICS XML ON 或查詢存儲

GO

-- 你的測試查詢
SELECT * FROM dbo.BigTable WHERE Col1 = 'Filter' ORDER BY Col2;
GO

-- 關閉統計 (養成習慣,避免影響後續批次)
SET STATISTICS PROFILE OFF;
SET STATISTICS IO OFF;
SET STATISTICS TIME OFF;
GO

輸出解讀指南 (重點看「訊息」頁籤)

1. STATISTICS TIME - CPU 與等待分析


SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 1 ms.  -- 解析/編譯階段

SQL Server Execution Times:
   CPU time = 15 ms, elapsed time = 120 ms. -- 執行階段
  • CPU time:實際消耗 CPU 周期。高 CPU** 通常意味著大量計算 (排序、雜湊、聚合、隱含轉換) 或計畫劣化。
  • Elapsed time:牆鐘時間。若 **Elapsed >> CPU**,表明大量**等待** (I/O 等待、鎖阻塞、網路傳輸、平行協調)。
  • Parse/Compile 時間高** → 計畫未重用 (動態 SQL 拼接、參數嗅探導致重編譯、統計更新觸發重編譯)。

2. STATISTICS IO - I/O 成本核心指標 (調優首看)


Table 'BigTable'. Scan count 1, logical reads 5000, physical reads 0, read-ahead reads 0, lob logical reads 0...
  • Logical Reads (邏輯讀)**:從緩存 (Buffer Pool) 讀取 8KB 頁面次數。**調優核心目標 = 最小化 Logical Reads**。直接反映查詢存取路徑效率 (Seek vs Scan、覆蓋索引、聯接策略)。
  • Physical Reads (物理讀)**:從磁碟讀取。冷緩存時出現;熱緩存應為 0。持續高物理讀 → 記憶體壓力 / 緩存命中率低。
  • Read-Ahead Reads (預讀)**:預測性大量讀取 (64KB/128KB/256KB)。全表掃描/大範圍掃描時出現。
  • LOB Logical Reads**:讀取 `MAX`/`XML`/`TEXT` 頁面。大物件存取開銷極大,應盡量避免 `SELECT *` 拉取 LOB 欄位。
  • Scan Count**:掃描/搜尋啟動次數。Nested Loops 內層表 Scan Count = 外層行數;Hash/ Merge Join 通常為 1。

3. STATISTICS PROFILE / XML - 計畫與基數估算驗證

  • 文字版 (`PROFILE`) 適合快速瀏覽;XML 版 (`XML`) 適合工具分析 (SSMS 圖形化、Plan Explorer、Query Store)。
  • 重點檢查:
    1. Actual Rows vs Estimated Rows** 差距 > 10x → 統計過時/參數嗅探/複雜運算式導致基數估算錯誤 → 計畫劣化根因。
    2. 運算子類型** : `Index Seek` (好) vs `Index Scan`/`Table Scan`/`Clustered Index Scan` (壞,除非刻意);`Key Lookup` (RID/Clustered) → 考慮覆蓋索引;`Sort`/`Hash Match`/`Spool` 高成本 → 檢查記憶體授予/索引順序。
    3. Parallelism** : `Parallelism (Gather/Repartition/Exchange Streams)` → 檢查 `MAXDOP`/`CTFP` 設定是否合理。
    4. Warnings** : `SpillToTempDb` (記憶體不足溢寫)、`Missing Index` (綠色提示)、`Implicit Conversion` (黃色警告)。

進階:Extended Events (XEvents) 取代 Profiler/Trace

`STATISTICS` 只能測單條查詢。生產環境持續監控需用 XEvents (輕量、可過濾、可持久化)。


-- 捕獲高耗時查詢 (超過 1 秒)
CREATE EVENT SESSION [LongRunningQueries] ON SERVER
ADD EVENT sqlserver.sql_statement_completed(
    ACTION(sqlserver.sql_text, sqlserver.database_name, sqlserver.username, sqlserver.client_hostname)
    WHERE ([duration] > 1000000) -- 微秒
)
ADD TARGET package0.event_file(SET filename=N'D:\XE\LongRunningQueries.xel', max_file_size=100, max_rollover_files=10)
WITH (MAX_MEMORY=4096 KB, EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS, MAX_DISPATCH_LATENCY=30 SECONDS);
GO
ALTER EVENT SESSION [LongRunningQueries] ON SERVER STATE = START;

實戰調優流程 (單查詢)

  1. `SET STATISTICS IO, TIME ON;` 執行查詢 → 記錄 **Logical Reads、CPU、Elapsed**。
  2. 查看 **Actual Execution Plan** (Ctrl+M) → 找 **最貴運算子** (Cost %最高) → 檢查 **Estimated vs Actual Rows**。
  3. 若 **Scan/Seek 不符預期** → 檢查 `WHERE`/`JOIN` 列索引覆蓋、SARGable、統計資訊 (`DBCC SHOW_STATISTICS`)。
  4. 若 **Sort/Hash Spill** → 檢查記憶體授予 (`Granted Memory` vs `Used Memory`)、`MAXDOP`、索引順序消除 Sort。
  5. 優化 (加索引/改寫/更新統計/Hint/Plan Guide) → 重測 → 對比 **Logical Reads / CPU / Elapsed** 下降幅度。

總結

「TIME 看 CPU/等待,IO 看邏輯讀 (核心),PROFILE/XML 看計畫與基數。」
養成「先開統計、跑查詢、關統計、看訊息、對計畫」的肌肉記憶,是 DBA 與開發者調優的基本功。

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