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

SQL 查詢效能調優:WHERE 子句常見陷阱與索引失效場景分析

     編輯:關於SqlServer

導致索引失效的五大 WHERE 子句寫法

即使欄位建有索引,不當的查詢寫法仍會導致掃描全表。以下為常見陷阱與改寫方案:

1. IS NULL / IS NOT NULL

  • 現象:B-Tree 索引預設不儲存 NULL 值 (除非為過濾索引或特定資料庫設定)。任何包含 NULL 的複合索引鍵該列會被排除。
  • 結果:優化器無法使用索引,強制全表掃描。
  • 對策:
    • 設計階段設定 NOT NULL DEFAULT 'N/A' 或預設值。
    • 查詢改寫:WHERE col = '' (空字串) 或 WHERE col = 0 (數值) 代替 NULL 判斷。
    • 若必須查 NULL,考慮建立 過濾索引 (Filtered Index, SQL 2008+):CREATE INDEX idx_col_notnull ON tbl(col) WHERE col IS NOT NULL;

2. 欄位聯結運算 (Concatenation)

錯誤:WHERE first_name + last_name = 'BillClinton'

正確:WHERE first_name = 'Bill' AND last_name = 'Clinton'

  • 聯結運算導致索引鍵值改變,優化器無法對應 last_name 索引。
  • 若應用層只有一個完整姓名變數,應在應用層拆分後再帶參數,或使用計算欄位 + 索引 (Persisted Computed Column)。

3. LIKE 通配符前置 (% 開頭)

全表掃描:WHERE last_name LIKE '%clinton%'

索引有效:WHERE last_name LIKE 'clin%' (前綴匹配)

  • 前置 % 導致無法利用 B-Tree 索引有序特性。
  • 全文檢索需求請使用 Full-Text Search 或 Elasticsearch 等專用引擎。

4. ORDER BY 非索引欄位或運算式

  • ORDER BY col + 1, ORDER BY UPPER(col) 會觸發昂貴的 Sort 運算子。
  • 解決:建立覆蓋索引包含排序欄位,或建立計算欄位索引。避免在 ORDER BY 使用運算式。

5. 否定邏輯 (NOT, !=, <>, !>, !<)

  • 否定條件通常導致索引掃描而非尋找,因需排除極少數值。
  • 改寫:WHERE status != 1 → WHERE status IN (0, 2, 3) (若值域固定小)。
  • 或使用 UNION ALL 拆分正向範圍查詢。

核心原則

SARGable (Search ARGument Able):查詢條件應保持「欄位單獨出現在運算子一側」,避免對欄位施加函數、運算、隱含轉換,才能有效利用索引尋找。

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