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

SQL Server 索引利用與非 SARG 條件深度解析:讓優化器「看見」你的索引

     編輯:關於SqlServer

核心概念:SARG (Search ARGument)

優化器能利用索引的前提是 WHERE 條件為 SARGable:column <op> constant,且 column 參與運算的「原樣」出現。

非 SARG 操作符清單(索引失效鐵律)

類別操作符/函數失效原因
否定邏輯NOT, <>, NOT IN, NOT EXISTS, NOT LIKE需掃描全表確認「不匹配」
隱式/顯式轉換CONVERT(), CAST(), UPPER(), LOWER(), RTRIM(), ISNULL(), COALESCE()列參與運算,無法直接對比索引鍵值
運算表達式col + 1 = 5, col * 2 > 10, ABS(col) = 5同左,列被計算
LIKE 通配符前置LIKE '%abc', LIKE '%abc%'B-Tree 只能從左匹配

實戰對比

-- 失效:列上有函數
SELECT * FROM Orders WHERE YEAR(OrderDate) = 2023;

-- 生效:改為範圍查詢
SELECT * FROM Orders 
WHERE OrderDate >= '2023-01-01' AND OrderDate < '2024-01-01';

檢測工具:查看執行計畫屬性

  • Index Seek = 索引生效。
  • Index Scan / Table Scan = 索引失效(或無索引)。
  • Predicate vs Seek Predicate:Seek Predicate 才是真正下推到存儲引擎的條件。

改寫清單

  1. WHERE ISNULL(col, '') = '' → WHERE col IS NULL OR col = ''(配合篩選索引)。
  2. WHERE UPPER(name) = 'ABC' → WHERE name = 'ABC' COLLATE Latin1_General_CI_AI 或建立計算欄索引。
  3. WHERE col NOT IN (subquery) → WHERE NOT EXISTS (SELECT 1 FROM ... WHERE ...)。
  4. WHERE col LIKE '%kw%' → 全文索引 / 外部搜尋引擎(Elasticsearch)。

進階:計算欄 + 索引

ALTER TABLE Orders ADD OrderYear AS YEAR(OrderDate) PERSISTED;
CREATE INDEX IX_Orders_OrderYear ON Orders(OrderYear);

查詢 WHERE OrderYear = 2023 即可 Seek。

總結口訣

「列不參與運算、不做隱式轉換、不加前置萬用字元、優先用 EXISTS 代替 NOT IN」—— 守住四條,索引失效少八成。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved