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

SQL 語句優化四大鐵律:避免函數運算欄位、型別一致、減少函數、拒絕 OR

     編輯:關於SqlServer

鐵律一:不要對欄位進行函數運算

-- 差:欄位參與運算,索引失效
WHERE -col1 = 5
WHERE col1 + 10 > 20
WHERE UPPER(name) = 'JOHN'
WHERE YEAR(create_date) = 2023

-- 好:運算移至常數側,索引可用
WHERE col1 = -5
WHERE col1 > 10
WHERE name = 'JOHN'  -- 配合大小寫不敏感排序規則
WHERE create_date >= '2023-01-01' AND create_date < '2024-01-01'

原理:SARGable (Search ARGument Able) — 欄位需「裸露」在比較運算子一側,優化器才能利用索引 Seek。

鐵律二:比較值與欄位型別保持一致

-- 差:隱含轉換,索引失效
WHERE int_col = '123'
WHERE varchar_col = 123

-- 好:顯式型別一致
WHERE int_col = 123
WHERE varchar_col = '123'

原理:字串與數值比較會雙向轉換為浮點數,導致索引不可用。

鐵律三:減少 WHERE 條件中的函數使用

-- 差:DATEDIFF 導致索引失效
WHERE DATEDIFF(day, create_date, GETDATE()) = 0

-- 好:範圍查詢,索引可用
WHERE create_date >= CAST(GETDATE() AS DATE)
  AND create_date < DATEADD(day, 1, CAST(GETDATE() AS DATE))

同理:ISNULL(col, '') = '' → col IS NULL OR col = ''(或建立過濾索引)

鐵律四:盡量避免 OR,改用 UNION ALL / IN / EXISTS

-- 差:OR 通常導致掃描
WHERE col1 = 1 OR col2 = 2

-- 好:UNION ALL 分別走索引再合併
SELECT * FROM T WHERE col1 = 1
UNION ALL
SELECT * FROM T WHERE col2 = 2

-- 好:IN 列表(單欄位多值)
WHERE status IN (1,2,3)

-- 好:EXISTS 替代 IN 子查詢
WHERE EXISTS (SELECT 1 FROM Ref WHERE Ref.ID = T.RefID AND Ref.Type = 'A')

例外:同一欄位多值 col IN (1,2,3) 會優化為 Seek;不同欄位 OR 才會掃描。

延伸優化清單

模式優化方向
LIKE '%keyword%'前導萬用字元無法用索引 → 全文檢索 / 反轉索引 / n-gram
!= / <> / NOT IN通常掃描 → 改寫為 NOT EXISTS / LEFT JOIN ... WHERE IS NULL
隱含轉換顯式 CAST/CONVERT 或修正參數型別
SELECT *明確列出欄位,減少 I/O、鎖爭用、網路傳輸
子查詢改為 JOIN / APPLY / CTE,避免重複執行
UNION無重複需求改用 UNION ALL,省去排序去重

驗證工具

  • 執行計畫 (Ctrl+M) — 看 Index Seek vs Scan、Key Lookup、Sort、Spool
  • SET STATISTICS IO, TIME ON — 邏輯讀取、CPU、耗時
  • sys.dm_exec_query_stats — 歷史執行統計
  • Database Engine Tuning Advisor — 索引建議
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved