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

SQL Server 查詢優化實戰:SARG 條件、索引失效陷阱與效能調優鐵律

     編輯:關於SqlServer

查詢優化器如何工作

SQL Server 擁有強大的**查詢優化器**,它會分析 WHERE 子句、可用索引、統計資料,自動選擇最佳執行計畫。**寫條件順序不影響結果**,優化器會自動重排。但開發者必須撰寫「可優化」的條件(SARG),讓優化器有機會使用索引。

SARG(Search Argument)定義

符合以下形式的條件稱為 SARG,優化器可利用索引快速定位:

欄位 運算子 常數/變數
常數/變數 運算子 欄位
欄位 運算子 常數/變數 AND 欄位 運算子 常數/變數 ...

運算子包含:=, >, <, >=, <=, BETWEEN, IN (常數清單), LIKE '前綴%'。

索引失效的 12 大陷阱(附實測對比)

#陷阱失效範例修正寫法原理
1LIKE 開頭萬用字元name LIKE '%張'name LIKE '張%'前綴固定才能索引搜尋
2OR 導致全表掃描name='張三' OR price>5000拆分為 UNION ALL 或改寫邏輯OR 兩側索引難合併
3否定運算子NOT, !=, <>, !<, !>, NOT IN, NOT EXISTS, NOT LIKE改用正向條件或覆蓋索引無法透過索引定位「不等於」
4欄位參與運算/函數ABS(price) < 5000
YEAR(date_col) = 2023
price BETWEEN -5000 AND 5000
date_col >= '2023-01-01' AND date_col < '2024-01-01'
運算破壞索引順序
5隱含轉換varchar_col = 123(數字比字串)varchar_col = '123'優化器對欄位做 CONVERT,索引失效
6IN 等同 ORtid IN (2,3)小清單可接受;大清單用 JOIN 臨時表內部展開為 OR
7NOT IN 子查詢含 NULLid NOT IN (SELECT nullable_col FROM t)NOT EXISTS (SELECT 1 FROM t WHERE t.col = outer.id)NULL 導致 NOT IN 永遠為 UNKNOWN
8EXISTS vs IN 效能迷思傳統認知 EXISTS 優於 IN實測**效能相同**,優化器內部轉換相同現代優化器已統一處理
9CHARINDEX vs LIKE '%...%'CHARINDEX('關鍵字', col) > 0同樣全表掃描,無優勢皆無法使用索引
10UNION 不一定優於 OR同欄位 OR 改 UNION 反而變慢同欄位用 IN 或單一範圍條件UNION 需合併排序去重
11SELECT * 殺手SELECT * FROM t只選需要欄位減少 I/O、鎖定、網路傳輸、覆蓋索引機會
12COUNT(*) vs COUNT(col)迷思 COUNT(*) 較慢實測 COUNT(*) ≈ COUNT(PK) < COUNT(其他欄位)優化器自動選最窄欄位統計

實測數據:欄位數量對查詢速度影響(10,000 筆測試)

ORDER BY 效能鐵律

查詢耗時邏輯讀
SELECT TOP 10000 gid, fariqi, reader, title FROM tgongwen ORDER BY gid DESC4,673 ms41,956
SELECT TOP 10000 gid, fariqi, title FROM tgongwen ORDER BY gid DESC1,376 ms—
SELECT TOP 10000 gid, fariqi FROM tgongwen ORDER BY gid DESC80 ms—
排序欄位10,000 筆耗時說明
無 ORDER BY196 ms依叢集索引自然順序
叢集索引欄位 (fariqi)156-173 ms**最快**,資料物理順序即邏輯順序
非叢集索引欄位 (gid-PK)4,720-4,736 ms需書籤查找/排序運算子

結論:排序欄位 = 叢集索引鍵 時效能最高;正序/倒序差異極小。

TOP 關鍵字:物理 I/O 的剋星

-- 只需前 10 筆,但子查詢排序 10,000 筆
SELECT TOP 10 * FROM (
    SELECT TOP 10000 gid, fariqi, title FROM tgongwen WHERE neibuyonghu='辦公室' ORDER BY gid DESC
) AS a ORDER BY gid ASC;

外層 TOP 10 讓引擎只輸出 10 列,**物理 I/O 大幅降低**,總耗時甚至**小於**子查詢單獨執行時間。善用 TOP 限制中間結果集大小,是大資料分頁、分批處理的核心技巧。

調優檢核清單

  1. WHERE 條件是否為 SARG 形式?
  2. 高選擇性欄位是否有索引?
  3. 是否避免 SELECT *?
  4. 排序欄位是否為叢集索引鍵?
  5. 大結果集是否使用 TOP / OFFSET-FETCH 限制?
  6. 統計資料是否最新?(UPDATE STATISTICS / 自動更新)
  7. 執行計畫是否出現「鍵值查找」、「排序」、「雜湊比對」等高成本運算子?
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved