执行位图索引扫描到仅索引扫描的原因?

Reason to perform Bitmap index scan to Index-only scan?

据我阅读 this 博客 post 了解,位图索引扫描可能优于索引扫描, 因为它批量访问 table 本身的页面以获取索引中不存在的数据。

然而,它仍然需要遍历索引,所以当所有请求的数据都在索引中时,我看不出为什么它可能比仅索引扫描更好。然而,在许多情况下,Postgres 似乎更喜欢位图索引扫描而不是仅索引扫描。

举个例子blog post:

#  INSERT INTO sampletable
        SELECT random() * 10000
        FROM generate_series(1, 100000);
# analyze sampletable;
# \d+ sampletable
                               Table "public.sampletable"
 Column |  Type  | Collation | Nullable | Default | Storage | Stats target | Description
--------+--------+-----------+----------+---------+---------+--------------+-------------
 x      | bigint |           |          |         | plain   |              |
Indexes:
    "sampletable_x_idx" btree (x)
# explain SELECT x FROM sampletable WHERE x < 10;
                                   QUERY PLAN
---------------------------------------------------------------------------------
 Bitmap Heap Scan on sampletable  (cost=5.01..234.48 rows=93 width=8)
   Recheck Cond: (x < 10)
   ->  Bitmap Index Scan on sampletable_x_idx  (cost=0.00..4.99 rows=93 width=0)
         Index Cond: (x < 10)
(4 rows)

那么我在理解 Index-Only/Bitmap 索引扫描的权衡方面缺少什么?

在 table 被清除之前,它只是名义上的仅索引扫描。每个元组都必须在堆中进行验证。计划者知道这一点,并惩罚索引只进行相应的扫描。一旦 table 被清除并且所有页面都设置为“全部可见”,那么规划器开始首选仅索引扫描。