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=# SET enable_bitmapscan = on; SET gaussdb=# EXPLAIN SELECT /*+ hashjoin(t_btm_test_1 t_btm_test_2 t_btm_test_3) BitmapScan(t_btm_test_2 idx_btm_test_21 idx_btm_test_22) BitmapScan(t_btm_test_3 idx_btm_test_31 )*/ * 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=7091.42..7475.66 rows=869 width=42) Hash Cond: (t_btm_test_1.c = t_btm_test_3.a) -> Index Scan using idx_btm_test_11 on t_btm_test_1 (cost=0.00..350.86 rows=9661 width=14) Index Cond: (a = 1::numeric) -> Hash (cost=7091.31..7091.31 rows=9 width=28) -> Hash Join (cost=1794.78..7091.31 rows=9 width=28) Hash Cond: (t_btm_test_3.c = t_btm_test_2.a) Join Filter: (((t_btm_test_2.a = 1::numeric) AND (t_btm_test_3.a = 1::numeric)) OR ((t_btm_test_2.a = 3::numeric) AND (t_btm_test_3.a = 3::numeric))) -> Bitmap Heap Scan on t_btm_test_3 (cost=439.65..4824.65 rows=20296 width=14) Recheck Cond: ((a = 1::numeric) OR (a = 3::numeric)) -> BitmapOr (cost=439.65..439.65 rows=20400 width=0) -> Bitmap Index Scan on idx_btm_test_31 (cost=0.00..224.50 rows=10700 width=0) Index Cond: (a = 1::numeric) -> Bitmap Index Scan on idx_btm_test_31 (cost=0.00..205.00 rows=9700 width=0) Index Cond: (a = 3::numeric) -> Hash (cost=1352.48..1352.48 rows=212 width=14) -> Bitmap Heap Scan on t_btm_test_2 (cost=657.66..1352.48 rows=212 width=14) Recheck Cond: ((b = 1::numeric) AND ((a = 1::numeric) OR (a = 3::numeric))) -> BitmapAnd (cost=657.66..657.66 rows=213 width=0) -> Bitmap Index Scan on idx_btm_test_22 (cost=0.00..217.25 rows=10267 width=0) Index Cond: (b = 1::numeric) -> BitmapOr (cost=440.10..440.10 rows=20733 width=0) -> Bitmap Index Scan on idx_btm_test_21 (cost=0.00..210.00 rows=9833 width=0) Index Cond: (a = 1::numeric) -> Bitmap Index Scan on idx_btm_test_21 (cost=0.00..230.00 rows=10900 width=0) Index Cond: (a = 3::numeric) (26 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运算,通过该操作组成匹配更复杂条件的位图。 |