执行位图索引扫描到仅索引扫描的原因?
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 被清除并且所有页面都设置为“全部可见”,那么规划器开始首选仅索引扫描。
据我阅读 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 被清除并且所有页面都设置为“全部可见”,那么规划器开始首选仅索引扫描。