通过阅读this博文我了解到,位图索引扫描可能优于索引扫描, 因为它批量访问表本身的页面以获取索引中不存在的数据。
然而,它仍然需要遍历索引,所以当所有请求的数据都存在于索引中时,我认为没有理由它可能比仅索引扫描更好。然而,在许多情况下,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)
那么我在理解仅索引/位图索引扫描的权衡方面缺少什么?
答案 0 :(得分:2)
在表被清空之前,它只是名称上的仅索引扫描。每个元组都必须在堆中进行验证。规划器知道这一点,并相应地惩罚索引只扫描。一旦表被清空并且所有页面都设置为“所有可见”,规划器就会开始首选仅索引扫描。