SQL 效能優劣在海量資料下可達百倍差距。優化器依賴索引,但不當寫法會導致隱性轉換、函數運算、邏輯否定使索引失效,退化為全表掃描。本文針對 WHERE 子句常見失效模式逐一破解。
WHERE col IS NULL 無法使用該列索引,必須全表掃描。DEFAULT '' 或 0),查詢改用 WHERE col = '' 或 WHERE col = 0 走索引。原則:索引列不可參與任何運算,否則優化器無法利用索引順序特性。
| 失效寫法 | 優化寫法 | 說明 |
|---|---|---|
WHERE last_name || first_name = 'BillClinton' | WHERE last_name = 'Clinton' AND first_name = 'Bill' | 拆分條件,各列獨立走索引 |
WHERE SUBSTR(col,1,3) = 'ABC' | WHERE col LIKE 'ABC%' | 前綴 LIKE 可用索引 |
WHERE TO_CHAR(date_col,'YYYYMMDD') = '20240101' | WHERE date_col >= DATE '2024-01-01' AND date_col < DATE '2024-01-02' | 範圍查詢保留索引 |
WHERE col + 0 = 100 (隱性轉換) | WHERE col = 100 | 避免型別轉換 |
% 使索引無法定位起始位置。keyword%、key%word 可使用索引(範圍掃描)。ORDER BY col 若 col 有索引 → 無排序成本。ORDER BY col1 + col2、ORDER BY UPPER(col) → 需額外排序(Filesort)。CREATE INDEX idx ON t(UPPER(col))、MySQL 8.0+ 支援)或調整查詢邏輯。NOT/!= 否定邏輯、IN vs EXISTS 子查詢優化、複合索引最左前綴原則、統計資訊收集與執行計畫分析。