條件欄位沒命中索引,索引仍有三種可能被用到

「WHERE 的欄位不在索引裡,索引就完全沒用了嗎?」——原則上沒有直接幫助,資料庫通常會放棄索引、改走全表掃描(見 全表掃描和索引掃描的適用場景是相反的)。但「沒有直接幫助」不等於「一定用不到」,索引還有三條間接的路。

1. 覆蓋索引 / 全索引掃描(Covering Index、Index Fast Full Scan)

條件欄位不在索引內,但這個查詢要用到的所有欄位(SELECT 加 WHERE 的全部)剛好都被某個複合索引包含 → 資料庫可能選擇遍歷整棵索引樹,而不是掃整張資料表。

理由是 I/O:索引頁通常比資料頁小得多,掃索引的頁數比掃表少,所以即使同樣是「全部掃一遍」,成本仍然低一截。

2. 排序或分組優化(ORDER BY / GROUP BY)

WHERE 用不到索引,但查詢帶 ORDER BY / GROUP BY,而那些欄位剛好有索引 → 資料庫有時會用索引來取得有序的結果,避開在記憶體或磁碟做昂貴的外部排序(filesort)。

索引幫的不是過濾,是排序。

3. 索引合併(Index Merge)

WHERE 由多個子條件組成(例如 A = 1 OR B = 2),只要其中某些欄位有索引 → 資料庫可以對有索引的部分走索引掃描,再把結果和其他條件合併過濾。

前提是至少有一個條件欄位命中索引;全都沒命中就用不上這條。

判準

查詢既沒有命中 WHERE 欄位的索引,又無法形成覆蓋索引 → 索引提供不了任何加速。

至於「那就補索引嗎」,欄位怎麼選見 複合索引的欄位 = Index Cond 的欄位 + Filter 裡的等值欄位,值不值得建見 建索引的代價是毫秒,收益可能是秒。