Index Cond 是在索引上定位,Filter 是撈出來再逐筆比

這兩個關鍵字並排在同一個節點裡時,它們講的是完全不同的成本——而它們的分界就是「索引夠不夠」的判準。

關鍵字發生什麼事成本
Index Cond直接在 B-Tree 索引樹上定位快
Filter索引條件不夠,把資料載進記憶體後一筆一筆用 CPU 比對每一筆都要付
Rows Removed by Filter比對完被丟棄的列數這個數字就是無用功的量

一個真實的例子

->  Bitmap Heap Scan on pg060 s  (actual time=496.333..496.333 rows=0 loops=15)
      Recheck Cond: (a.vrfy_wkym = vrfy_wkym)
      Filter: ((a.div_no = (div_no)::bpchar) AND (a.emp_org_id = (emp_org_id)::bpchar))
      Rows Removed by Filter: 38118
      ->  Bitmap Index Scan on pg060_idx1  (actual ... rows=38118 loops=15)
            Index Cond: (vrfy_wkym = a.vrfy_wkym)

攤開來看發生了什麼:

索引只幫上 vrfy_wkym 這一個條件
  → 撈出該年月整整 38,118 筆
  → div_no 和 emp_org_id 只能在記憶體裡逐筆比
  → 38,118 筆【全部】不符合,被丟棄
  → 真正要的是 0 筆
  → 而且這整個過程重複了 15 次 → 38,118 × 15 ≈ 57 萬次比對

單次 496 ms,這一個節點就吃掉 7.4 秒。

判準

Rows Removed by Filter 很大(數千到數十萬),就代表資料庫做了大量無用功。

而且它指出了處方:被 Filter 丟掉的那些欄位,就是該補進索引的欄位——見 複合索引的欄位 = Index Cond 的欄位 + Filter 裡的等值欄位。

Rows Removed by Filter 和「回傳幾列 vs 看過幾列」的對應關係見 WHERE 決定回傳幾列,索引才決定要看過幾列。