開發初期資料量小感覺不出 SQL 效能差異,上線後資料增長,劣質 SQL 與優質 SQL 速度可差上百倍。優化核心在於讓優化器使用索引,避免全表掃描。
問題:任何包含 NULL 的欄位不會被納入索引 (即使複合索引,只要一欄有 NULL 整列排除)。WHERE 條件用 IS NULL 或 IS NOT NULL 直接導致全表掃描。
對策:
NOT NULL DEFAULT '' 或預設值col = '' 或 col = 0 等具體值比較問題:WHERE first_name || ' ' || last_name = 'Bill Clinton' — 即使 last_name 有索引,聯接運算導致索引失效。
修正:
-- 拆解為獨立條件,各自命中索引
WHERE first_name = 'Bill' AND last_name = 'Clinton'
變數情況:應用層拆分變數再傳參數,勿在 SQL 內用 SUBSTR/INSTR 處理索引欄位。
問題:WHERE last_name LIKE '%clinton%' — 開頭 % 導致索引失效。
可用索引:WHERE last_name LIKE 'c%' — 通配符在後方可用索引。
對策:
FULLTEXT 索引或專用搜尋引擎前綴% 形式問題:ORDER BY col + 1、ORDER BY UPPER(name)、ORDER BY 非索引欄位 會觸發 filesort,大量資料極慢。
對策:
ORDER BY 僅用索引欄位WHERE id > last_id ORDER BY id LIMIT N 替代 OFFSET問題:WHERE NOT (status = 1)、WHERE col != 'value'、WHERE col NOT IN (...) 常導致優化器放棄索引。
修正:
WHERE status IN (0,2,3)、WHERE col = 'other_value'NOT EXISTS 通常比 NOT IN 效能好 (尤其子查詢回傳 NULL 時)UNION ALL 重寫EXPLAIN 確認 type、key、rowsSELECT 索引欄位 FROM ... 避免回表