萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> 資料庫綜合

SQL 命令優化九大鐵律:從全表掃描到索引覆蓋的實戰指南

前言

SQL 優化自資料庫誕生以來即為永恆議題。優化器雖智能,但受限於統計資訊、語法結構、索引設計,仍需開發者遵循核心原則撰寫高效 SQL。本文提煉九大鐵律,配合原理解析與改寫對照,助你避開效能陷阱。

九大鐵律速查表

#鐵律錯誤範例優化寫法核心原理
1按需選欄,拒絕 SELECT *SELECT * FROM tSELECT id, name, amt FROM t減少 I/O、網路、記憶體;利用覆蓋索引
2判斷存在用 EXISTS,不用 COUNT(*)IF (SELECT COUNT(*) FROM t WHERE ...) > 0IF EXISTS (SELECT 1 FROM t WHERE ...)EXISTS 短路,找到一筆即停;COUNT 需全掃
3優先 EXISTS 替代 IN/NOT INWHERE deptno NOT IN (SELECT deptno FROM emp)WHERE NOT EXISTS (SELECT 1 FROM emp WHERE dept.deptno = emp.deptno)IN 易退化為全掃;NOT IN 遇 NULL 邏輯陷阱
4NOT IN 改 LEFT JOIN ... IS NULLWHERE id NOT IN (SELECT id FROM t2)FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.id IS NULLJOIN 可利用索引、並行,計畫穩定
5拒絕 OR,改用 UNION ALLWHERE a=1 OR b=2WHERE a=1 UNION ALL WHERE b=2OR 導致索引合併失敗,全掃;UNION ALL 分別走索引
6WHERE 條件順序匹配索引順序,範圍從大到小索引 (a,b,c) → WHERE c=1 AND a=2WHERE a=2 AND c=1復合索引最左前綴;高選擇性優先
7優先 >= 避免 >WHERE id > 100WHERE id >= 101邊界值下推,利用索引 Seek 而非 Scan(視統計資訊)
8WHERE 禁用函數/運算/隱式轉換WHERE SUBSTRING(name,1,3)='abc'
WHERE DATEDIFF(day, dt, '2024-01-01')=0
WHERE name LIKE 'abc%'
WHERE dt >= '2024-01-01' AND dt < '2024-01-02'
欄位運算導致 SARGable 失效,索引不可用
9深知索引結構,避開失效模式WHERE col IS NULL / <> / != / NOT / NOT LIKE改寫為正向條件、覆蓋索引、計算欄位+索引負向條件、NULL 判斷、隱式轉換均導致全掃

核心原理深度解析

SARGable (Search ARGument Able) 原則

「可用索引尋找的引數」:WHERE 條件必須讓優化器能直接對索引鍵值進行範圍定位。任何欄位側運算、函數、隱式轉換都會破壞 SARGable,迫使 Scan。

統計資訊與參數嗅探

即使寫法正確,過期統計資訊或參數嗅探也可能導致錯誤計畫。定期 UPDATE STATISTICS、使用 OPTION (RECOMPILE) 或 OPTIMIZE FOR UNKNOWN 緩解。

索引維護成本

每個索引約增加 10~20% 寫入開銷。定期評估 sys.dm_db_index_usage_stats,移除長期未被讀取的索引。

結語

九大鐵律非絕對真理,但覆蓋 90% 以上常見效能問題。養成「先看執行計畫、再寫 SQL、後驗證 IO/時間」的習慣,配合定期索引健檢,才是持續交付高效能 SQL 的正道。

copyright © 萬盛學電腦網 all rights reserved