更新时间:2025-05-29 GMT+08:00
Bitmap
算子说明
- Bitmap Index Scan,位图索引扫描,该算子的作用为用索引扫描的方式,将过滤出的符合条件的元组的tid形成一张位图并向上返回。多个表扫描出的多个结果位图之间可再做 BitmapAnd或者BitmapOr操作,相比于Index Scan还需要对表与表之间筛选出来的元组进行比对,可减少过滤时间。
- Bitmap Heap Scan,位图堆扫描,该算子的下层通常有Bitmap Index Scan,作用为通过扫描下层算子返回的位图(bitmap)来判断哪些元组符合条件并取出然后向上返回。当优化器通过代价估算选择采用Bitmap Index Scan的扫描方式,且需要返回符合条件的元组时,通常上层会配套使用Bitmap Heap Scan来通过扫描位图过滤选取元组并返回。
- BitmapOr,位图或操作,该算子作用为将下层的bitmap进行或操作,返回操作后的位图。
- BitmapAnd,位图与操作,该算子作用为将下层的bitmap进行与操作,返回操作后的位图。
使用Bitmap Index Scan和Bitmap Heap Scan的前提条件为:GUC参数enable_bitmapscan设置为on。
典型场景
多个表做关联,且在一个或多个表的关联列上有可用的索引,部分或全部表的表数据足够大。
示例
示例:多表连接带索引。
--数据准备,创建3个表,数据均为numeric类型,随机填充数据,为每个表的每个属性创建索引。 gaussdb=# SET enable_default_ustore_table = on; SET gaussdb=# CREATE TABLE t_btm_test_1(a numeric,b numeric,c numeric); CREATE TABLE gaussdb=# CREATE TABLE t_btm_test_2(a numeric,b numeric,c numeric); CREATE TABLE gaussdb=# CREATE TABLE t_btm_test_3(a numeric,b numeric,c numeric); CREATE TABLE gaussdb=# DECLARE n1 numeric := 100; n2 numeric := 0; n3 numeric := 100; BEGIN WHILE n1 > 0 LOOP WHILE n2 < 100 LOOP WHILE n3 > 0 LOOP INSERT INTO t_btm_test_1 VALUES(n1, n2, n3); INSERT INTO t_btm_test_2 VALUES(n1, n3, n2); INSERT INTO t_btm_test_3 VALUES(n2, n1, n3); n3 := n3 - 1; END LOOP; n2 := n2 + 1; END LOOP; n1 := n1 - 1; END LOOP; END; / ANONYMOUS BLOCK EXECUTE gaussdb=# CREATE INDEX idx_btm_test_11 ON t_btm_test_1 USING UBTREE (a); CREATE INDEX gaussdb=# CREATE INDEX idx_btm_test_12 ON t_btm_test_1 USING UBTREE (b); CREATE INDEX gaussdb=# CREATE INDEX idx_btm_test_13 ON t_btm_test_1 USING UBTREE (c); CREATE INDEX gaussdb=# CREATE INDEX idx_btm_test_21 ON t_btm_test_2 USING UBTREE (a); CREATE INDEX gaussdb=# CREATE INDEX idx_btm_test_22 ON t_btm_test_2 USING UBTREE (b); CREATE INDEX gaussdb=# CREATE INDEX idx_btm_test_23 ON t_btm_test_2 USING UBTREE (c); CREATE INDEX gaussdb=# CREATE INDEX idx_btm_test_31 ON t_btm_test_3 USING UBTREE (a); CREATE INDEX gaussdb=# CREATE INDEX idx_btm_test_32 ON t_btm_test_3 USING UBTREE (b); CREATE INDEX gaussdb=# CREATE INDEX idx_btm_test_33 ON t_btm_test_3 USING UBTREE (c); CREATE INDEX gaussdb=# ANALYZE t_btm_test_1; ANALYZE gaussdb=# ANALYZE t_btm_test_2; ANALYZE gaussdb=# ANALYZE t_btm_test_3; ANALYZE --执行结果。 gaussdb=# SET enable_bitmapscan = on; SET gaussdb=# EXPLAIN SELECT /*+ HashJoin(t_btm_test_2 t_btm_test_3 t_btm_test_1) Leading(((t_btm_test_2 t_btm_test_3) t_btm_test_1)) NestLoop(t_btm_test_2 t_btm_test_3) BitmapScan(t_btm_test_2 idx_btm_test_22 idx_btm_test_21 idx_btm_test_21) BitmapScan(t_btm_test_3 idx_btm_test_31 idx_btm_test_31) TableScan(t_btm_test_1)*/ * FROM t_btm_test_1 , t_btm_test_2 , t_btm_test_3 WHERE t_btm_test_1.a = t_btm_test_2.b AND t_btm_test_2.a = t_btm_test_3.c AND t_btm_test_3.a = t_btm_test_1.c AND t_btm_test_1.a = 1 AND ( (t_btm_test_2.a = 1 AND t_btm_test_3.a = 1) OR (t_btm_test_2.a = 3 AND t_btm_test_3.a = 3) ); QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------- Hash Join (cost=23.80..31.87 rows=1 width=39) Hash Cond: (t_btm_test_3.a = t_btm_test_1.c) -> Nested Loop (cost=21.54..29.59 rows=1 width=26) Join Filter: ((t_btm_test_2.a = t_btm_test_3.c) AND (((t_btm_test_2.a = 1) AND (t_btm_test_3.a = 1)) OR ((t_btm_test_2.a = 3) AND (t_btm_test_3.a = 3)))) -> Bitmap Heap Scan on t_btm_test_2 (cost=13.02..17.04 rows=1 width=13) Recheck Cond: ((b = 1) AND ((a = 1) OR (a = 3))) -> BitmapAnd (cost=13.02..13.02 rows=1 width=0) -> Bitmap Index Scan on idx_btm_test_22 (cost=0.00..4.26 rows=1 width=0) Index Cond: (b = 1) -> BitmapOr (cost=8.52..8.52 rows=1 width=0) -> Bitmap Index Scan on idx_btm_test_21 (cost=0.00..4.26 rows=1 width=0) Index Cond: (a = 1) -> Bitmap Index Scan on idx_btm_test_21 (cost=0.00..4.26 rows=1 width=0) Index Cond: (a = 3) -> Bitmap Heap Scan on t_btm_test_3 (cost=8.52..12.53 rows=1 width=13) Recheck Cond: ((a = 1) OR (a = 3)) -> BitmapOr (cost=8.52..8.52 rows=1 width=0) -> Bitmap Index Scan on idx_btm_test_31 (cost=0.00..4.26 rows=1 width=0) Index Cond: (a = 1) -> Bitmap Index Scan on idx_btm_test_31 (cost=0.00..4.26 rows=1 width=0) Index Cond: (a = 3) -> Hash (cost=2.25..2.25 rows=1 width=13) -> Seq Scan on t_btm_test_1 (cost=0.00..2.25 rows=1 width=13) Filter: (a = 1) (24 rows) --删除表。 gaussdb=# DROP TABLE t_btm_test_1, t_btm_test_2, t_btm_test_3;
上述示例中,Bitmap Heap Scan算子输出信息如下所示。
信息名称 |
含义 |
---|---|
Bitmap Heap Scan |
算子的名称。 |
Recheck Cond |
在执行索引扫描后,数据库重新检查过滤的谓词,示例中Recheck Cond: ((a = 1::numeric) OR (a = 3::numeric))的过滤条件为,a列的值等于1或者等于3。在查询执行时,满足这些条件的行会被包含在最终的结果集中。 |
上述示例中,Bitmap Index Scan算子输出信息如下所示。
信息名称 |
含义 |
---|---|
Bitmap Index Scan |
算子的名称。 |
Index Cond |
该算子的过滤谓词,在查询执行时,满足这些条件的行会被包含在最终的结果集中。 |
上述示例中,BitmapOr & BitmapAnd算子输出信息如下所示。
信息名称 |
含义 |
---|---|
BitmapOr |
算子的名称,代表将下层返回的bitmap进行or运算,通过该操作组成匹配更复杂条件的位图。 |
BitmapAnd |
算子的名称,代表将下层返回的bitmap进行and运算,通过该操作组成匹配更复杂条件的位图。 |
父主题: 表访问方式