1、什么是bitmap scan?


bitmap scan是pg中表的扫描计划的一种。


在pg中,对表的扫描计划有:

  • Seq Scan

  • Index Scan

  • Bitmap Heap Scan

  • Index Only Scan


对于bitmap scan这种,使用explain查看查询语句的执行计划,会得到类似如下的返回:


bill=# explain select * from t1 where c1 =10 and c2 =20 and c3 = 30;  

                                 QUERY PLAN                                  

-----------------------------------------------------------------------------

 Bitmap Heap Scan on t1  (cost=3.31..4.62 rows=1 width=12)

   Recheck Cond: ((c3 = 30) AND (c2 = 20))

   Filter: (c1 = 10)

   ->  BitmapAnd  (cost=3.31..3.31 rows=1 width=0)

         ->  Bitmap Index Scan on idx_t13  (cost=0.00..1.53 rows=10 width=0)

               Index Cond: (c3 = 30)

         ->  Bitmap Index Scan on idx_t12  (cost=0.00..1.53 rows=10 width=0)

               Index Cond: (c2 = 20)

(8 rows)



2、bitmap scan 具体是怎么工作的?


bitmap scan 一般是发生在对多个单列索引,使用组合查询的SQL中。


比如上面的例子中:'select * from t1 where c1 =10 and c2 =20 and c3 = 30;'  

, c1、c2、c3都是索引列。


Bitmap SCAN是对查询条件中的每个索引构造一个bitmap串。bitmap串中,每个bit位对应一个heap page,  heap page中有符合条件的行,该bit位就会被标记为1。


如下所示:

|100000000001000000010000000000000111100000000| bitmap c1

根据条件中索引列的多少,就组成了多个bitmap


当所有索引列的位图创建完成,就对它们执行位与运算(BitmapAnd)。


注:下面的演示中为了方便,只演示了两个索引列的情况,另外不一定都是位与运算,还可能是位或运算(BitmapOR)。

+---------------------------------------------+|100000000001000000010000000000000111100000000| bitmap 1|000001000001000100010000000001000010000000010| bitmap 2 &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&|000000000001000000010000000000000010000000000| Combined bitmap+-----------+-------+--------------+----------+            |       |              |            v       v              vUsed to scan the heap only for matching pages:+---------------------------------------------+|___________X_______X______________X__________|+---------------------------------------------+

位图堆扫描(Bitmap Heap Scan)然后寻找每一页的开头,并读取符合条件的页面:

+---------------------------------------------+|___________X_______X______________X__________|+---------------------------------------------+seek------->^seek-->^seek--------->^            |       |              |            ------------------------            only these pages read



3、bitmap scan和index scan的区别是什么?


index scan : 是对于给定的查询,先扫描一遍索引,从索引中找到符合要求的记录的指针,再定位到表中具体的page去取。


Bitmap scan:普通的index scan每次从索引中获取一个元组指针,并立即访问表中的元组,那么一个 PAGE 有可能被多次访问,而位图扫描一次性从索引中获取所有的元组指针,使用内存中的“位图”数据结构对它们进行排序,然后按物理元组位置顺序访问表元组。它的核心思想是单个page在扫描期间只访问一次



4、Bitmap Scan的优点是什么?


bitmap scan的作用就是通过建立位图的方式,将index scan 回表过程中对页访问的随机性IO转换为顺行性行为,从而减少查询过程中IO的消耗。 



5、Bitmap Scan的缺点是什么?


从上面的分析中可以看出,Bitmap的优化是通过bitmap的生成过程中增加内存与CPU的消耗来减少IO消耗。



6、总结?


注:下面这段说的特别好,原文:https://www.cnblogs.com/wy123/p/13376991.html


任何优化都是一个系统工程,而不是一个单点工程,通过不同资源的消耗比例来提升整体的性能。

如果是高性能存储或者有充足的内存,并不一定总是发生物理IO,那么IO并不一定会是瓶颈,相反机械地去做bitmap的生成的话,反倒是一种浪费。此时可以根据具体的IO能力,比如磁盘的随机读和顺序读代价参数,或者是禁用bitmap scan等,来做整体上的优化方案。


https://mp.weixin.qq.com/s/r3Gmc51Mf9mimXgCeAB59A