SQL 查詢優化是資料庫效能調校的核心環節。撰寫高效率的 SQL 不僅能大幅縮短回應時間,更能降低伺服器資源消耗,提升系統整體吞吐量。本文系統整理了實戰中常見的優化策略,涵蓋索引設計、查詢改寫、資料型別選擇、臨時表與游標使用等關鍵面向,供開發與 DBA 參考。
避免全表掃描是優化的首要目標。在 WHERE、ORDER BY 及 JOIN 涉及的欄位上建立合適索引,能讓優化器快速定位資料。
若索引為復合索引,查詢條件必須包含索引的第一個欄位,且盡量按索引欄位順序撰寫條件,否則索引可能失效。
索引雖加速查詢,但會拖慢 INSERT、UPDATE、DELETE(需維護索引結構)。單表索引建議不超過 6 個;若過多,需評估低頻索引是否必要。
叢集索引決定資料物理存儲順序。頻繁修改叢集索引鍵會導致頁分裂與資料重排,消耗大量 I/O。若業務頻繁更新該欄,考慮改為非叢集索引。
SELECT *明確列出所需欄位,減少網路傳輸與 I/O,並能利用覆蓋索引。
任何對欄位的運算(如 num/2 = 100)、函數(如 SUBSTRING(name,1,3)='abc')、類型轉換都會導致索引失效,應將運算移至等號右側(num = 200、name LIKE 'abc%')。
EXISTS 替代 IN / NOT INEXISTS 支援短路機制,僅需找到一筆符合即返回,效能通常優於 IN。對連續數值優先用 BETWEEN。
OR 導致全表掃描若 OR 兩側欄位索引覆蓋不全,優化器傾向全掃。可改寫為 UNION ALL 分別走索引再合併。
LIKE '%keyword%' 前導萬用字元前導 % 無法利用索引。若需模糊搜尋,考慮全文檢索或反轉索引技巧。
區域變數在編譯時值未知,可能導致參數嗅探問題或全掃。必要時可用 WITH (INDEX(...)) 強制指定索引,或採用動態 SQL/重新編譯選項緩解。
如 SELECT ... WHERE 1=0 產生空表結構,應改用 CREATE TABLE。
VARCHAR/NVARCHAR 取代 CHAR/NCHAR:變長欄位節省空間,掃描範圍更小。NULL:CHAR 型固定長度,NULL 同樣佔空間;VARCHAR 則不佔。建議非必要欄位設 NOT NULL + 預設值,簡化判斷邏輯。UPDATE 僅修改異動欄位,避免全行寫入產生大量日誌與鎖爭用。
避免長事務鎖表阻塞業務。採用 TOP (N) / LIMIT / ROWNUM 迴圈分批處理,批次間 SLEEP 釋放鎖,範例:
WHILE (1=1)
BEGIN
DELETE TOP (1000) FROM logs WHERE log_date <= '2012-11-01';
IF @@ROWCOUNT = 0 BREAK;
WAITFOR DELAY '00:00:00.05'; -- 50ms
END
COUNT(*)全表掃描且無業務意義,嚴禁上線。
SELECT INTO 減少日誌;小量資料用 CREATE TABLE + INSERT。TRUNCATE TABLE → DROP TABLE,避免系統表長時間鎖定。FAST_FORWARD 游標。SET NOCOUNT ON/OFF,抑制 DONE_IN_PROC 訊息,減少網路往返。SQL 優化無銀彈,需結合執行計畫、索引統計資訊、業務存取模式綜合判斷。建立「先測量、再優化、後驗證」的閉環習慣,方能持續產出高效能 SQL。