首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

SQL Server 查詢優化器與 SARG 原理深度解析:寫出高性能 WHERE 條件

     編輯:MySQL 資料庫相關知識

SQL Server 擁有強大的查詢優化器,但理解 SARG (Search ARGument) 原理才能寫出真正能用上索引的 WHERE 條件。本文系統講解 SARG 定義、優化器工作機制、7 大實戰優化法則與常見誤區實測對比。

SARG 核心定義

形式:列名 操作符 <常數/變量> 或 <常數/變量> 操作符 列名

合格操作符:=, >, <, >=, <=, BETWEEN, IN (部分), LIKE '前綴%'

核心價值:優化器能識別 SARG,將其轉化為 索引查找 而非 索引掃描/表掃描。

優化器工作流程

  1. 解析 SQL → 生成邏輯樹
  2. 分析 WHERE 子句每個謂詞,判斷是否為 SARG
  3. 統計信息估算各訪問路徑代價 (I/O、CPU、內存)
  4. 選擇最低代價執行計劃 (索引查找 > 索引掃描 > 表掃描)
  5. 執行計劃緩存復用 (參數化查詢受益最大)

7 大實戰優化法則 (含反例)

#法則✅ SARG 例❌ 非 SARG 例根因
1LIKE 僅前綴通配符可用索引name LIKE '張%'name LIKE '%張' / name LIKE '%張%'前導通配符導致索引無法定位
2OR 導致全表掃描name='張三' AND age>30name='張三' OR age>30OR 無法合併索引查找範圍
3否定/函數破壞 SARGprice > 5000NOT (price>5000), ABS(price)<5000, price*2>10000列上運算/函數使索引鍵值不可用
4IN 等價 OR (大列表慎用)id IN (1,2,3)id IN (SELECT ...) 子查詢可能退化IN 列表過長優化器可能轉表掃描
5盡量少用 NOTstatus = 'active'status != 'deleted'否定謂詞難利用索引
6EXISTS ≈ IN 性能 (實測)EXISTS (SELECT 1 FROM t2 WHERE t2.id=t1.id)IN (SELECT id FROM t2)現代優化器對兩者等價轉換,統計信息準確時性能一致
7CHARINDEX ≈ LIKE '%...%' (全掃描)—CHARINDEX('關鍵字', col)>0 vs col LIKE '%關鍵字%'實測 7 秒 vs 7 秒,邏輯讀 7155 vs 7155,無性能差異

實測數據證據 (pubs 庫 titles/sales 表)


-- IN 子查詢
SELECT title,price FROM titles WHERE title_id IN (SELECT title_id FROM sales WHERE qty>30)
-- 掃描 18 次,邏輯讀 56

-- EXISTS 子查詢
SELECT title,price FROM titles WHERE EXISTS (SELECT 1 FROM sales WHERE sales.title_id=titles.title_id AND qty>30)
-- 掃描 18 次,邏輯讀 56  (完全一致)

進階優化技巧

  • 強制索引:WITH (INDEX(idx_name)) (謹慎,統計信息過期時可能適得其反)
  • 更新統計信息:UPDATE STATISTICS table / sp_updatestats — 優化器決策基石
  • 查看執行計劃:SSMS Ctrl+M / SET SHOWPLAN_ALL ON — 關注 Index Seek vs Scan
  • 參數化查詢:sp_executesql 復用計劃,避免參數嗅探問題 (可用 OPTION (RECOMPILE) 緩解)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved