我将通过以下示例来解释我的误解。
我不明白基本面的Bitmap Heap Scan Node
。考虑查询SELECT customerid, username FROM customers WHERE customerid < 1000 AND username <'user100';
的计划是这样的:
Bitmap Heap Scan on customers (cost=25.76..61.62 rows=10 width=13) (actual time=0.077..0.077 rows=2 loops=1)
Recheck Cond: (((username)::text < 'user100'::text) AND (customerid < 1000))
-> BitmapAnd (cost=25.76..25.76 rows=10 width=0) (actual time=0.073..0.073 rows=0 loops=1)
-> Bitmap Index Scan on ix_cust_username (cost=0.00..5.75 rows=200 width=0) (actual time=0.006..0.006 rows=2 loops=1)
Index Cond: ((username)::text < 'user100'::text)
-> Bitmap Index Scan on customers_pkey (cost=0.00..19.75 rows=1000 width=0) (actual time=0.065..0.065 rows=999 loops=1)
Index Cond: (customerid < 1000)
我对这个节点的理解:
正如所解释的存在,在bitmap heap scan
读取顺序表块,所以它不会产生这恰好刚刚做随机表访问开销Index Scan
。
完成之后Index Scan
,PostgreSQL不知道如何最佳地获取行,以避免不必要的heap blocks reads
(或hits
是否有热缓存)。因此为了弄清楚它生成的结构(Bitmap Index Scan
)bitmap
,在我的例子中是通过生成索引的两个位图并执行而生成的BITWISE AND
。由于已生成位图,因此它现在可以按顺序最佳地读取表,从而避免了不必要的操作heap I/O-operations
。
那是很多问题出现的地方。
问题:我们只有一个位图。PostgreSQL如何仅通过位图了解有关行的物理顺序的任何信息?还是生成位图,以便它的任何元素都可以轻松地映射到指向页面的指针?如果是这样,那就解释了一切,但这只是我的猜测。
因此,我们可以简单地说一下bitmap heap scan -> bitmap index scan
,就像顺序扫描一样,但是仅扫描表的适当部分吗?
001001010101011010101
。还是实际上并不重要,我们所需要知道的只是可以通过位图以相当快的方式找到一个块...?