postgres中的Seq Scan和Bitmap堆扫描有什么区别?

时间:2009-01-04 06:52:45

标签: optimization postgresql query-optimization sql-execution-plan

在explain命令的输出中,我找到了两个术语'Seq Scan'和'Bitmap heap Scan'。有人能告诉我这两种类型的扫描有什么区别吗? (我正在使用PostgreSql)

1 个答案:

答案 0 :(得分:68)

http://www.postgresql.org/docs/8.2/static/using-explain.html

基本上,顺序扫描将转到实际行,并从第1行开始读取,并继续直到查询得到满足(这可能不是整个表,例如,在限制的情况下)

位图堆扫描意味着PostgreSQL找到了一小部分行来获取(例如,从索引中获取),并且只能获取那些行。这当然会有更多的搜索,所以只有当它需要一小部分行时才会更快。

举个例子:

create table test (a int primary key, b int unique, c int);
insert into test values (1,1,1), (2,2,2), (3,3,3), (4,4,4), (5,5,5);

现在,我们可以轻松获得seq扫描:

explain select * from test where a != 4

                       QUERY PLAN                        
---------------------------------------------------------
 Seq Scan on test  (cost=0.00..34.25 rows=1930 width=12)
   Filter: (a <> 4)

它进行了一次顺序扫描,因为它估计它将占据绝大多数的表格;寻求这样做(而不是一个大的,无聊的阅读)将是愚蠢的。

现在,我们可以使用索引:

explain select * from test where a = 4 ;
                              QUERY PLAN                              
----------------------------------------------------------------------
 Index Scan using test_pkey on test  (cost=0.00..8.27 rows=1 width=4)
   Index Cond: (a = 4)

最后,我们可以获得一些位图操作:

explain select * from test where a = 4 or a = 3;
                                  QUERY PLAN                                  
------------------------------------------------------------------------------
 Bitmap Heap Scan on test  (cost=8.52..13.86 rows=2 width=12)
   Recheck Cond: ((a = 4) OR (a = 3))
   ->  BitmapOr  (cost=8.52..8.52 rows=2 width=0)
         ->  Bitmap Index Scan on test_pkey  (cost=0.00..4.26 rows=1 width=0)
               Index Cond: (a = 4)
         ->  Bitmap Index Scan on test_pkey  (cost=0.00..4.26 rows=1 width=0)
               Index Cond: (a = 3)

我们可以将其读作:

  1. 为a = 4构建我们想要的行的位图。 (位图索引扫描)
  2. 为a = 3构建我们想要的行的位图。 (位图索引扫描)
  3. 或两个位图一起(BitmapOr)
  4. 查看表格中的那些行(位图堆扫描)并检查以确保a = 4或a = 3(重新检查cond)
  5. [是的,这些查询计划是愚蠢的,但那是因为我们无法分析test如果我们分析它,它们都是顺序扫描,因为有5个小行]