EXPLAINでIndex-Only Scanと出ていても、実データにアクセスしている場合がある

PostgreSQLでIndex-Only Scanが有効になるのは、Visibility Mapが0(ブロック中、不要なタプルが存在しない、かつどのトランザクションも更新していない)のときのみ。
あるブロックに対して、INSERT、UPDATE、DELETEが行われると、VACUUMが実行されるまで、Index-Only Scanが有効にならない。

Index-Only Scanが効いているか確認する簡単な方法は、EXPLAINではなく、EXPLAIN ANALYZEを実行し、Heap Fetchesが0になっているかどうかを見ること。

もし、Visibility Mapが1で実際にはタプルにアクセスしていれば、Heap Fetchesが1以上となる。
INSERTしかしていなければ、ブロック中、該当のidを持ったデータは1件なので、アクセスするタプルは1件である。
VACUUM後、(HOTが効かない場合に限るが)UPDATEを2度していれば最新のデータにたどり着くまでに3回かかり、Heap Fetches: 3となる。

-PostgreSQL