Optimization postgres中的Seq扫描和位图堆扫描有什么区别?

Optimization postgres中的Seq扫描和位图堆扫描有什么区别?,optimization,postgresql,query-optimization,sql-execution-plan,Optimization,Postgresql,Query Optimization,Sql Execution Plan,在explain命令的输出中,我找到了两个术语“Seq Scan”和“位图堆扫描”。有人能告诉我这两种扫描的区别吗?(我正在使用PostgreSql) 基本上,顺序扫描是到实际的行,并从第1行开始读取,然后继续,直到满足查询(这可能不是整个表,例如,在限制的情况下) 位图堆扫描意味着PostgreSQL已经找到了一小部分要提取的行(例如,从索引中),并且只提取这些行。这当然会有更多的搜索,所以只有当它需要一小部分行时才会更快 例如: create table test (a int primar

在explain命令的输出中,我找到了两个术语“Seq Scan”和“位图堆扫描”。有人能告诉我这两种扫描的区别吗?(我正在使用PostgreSql)

基本上,顺序扫描是到实际的行,并从第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);
现在,我们可以轻松获得序列扫描:

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 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)
我们可以这样理解:

  • 为a=4构建所需行的位图。(位图索引扫描)
  • 为a=3生成所需行的位图。(位图索引扫描)
  • 或将两个位图放在一起(位图或)
  • 在表中查找这些行(位图堆扫描),并检查以确保a=4或a=3(重新检查cond)

  • [是的,这些查询计划很愚蠢,但那是因为我们没有分析
    测试
    ,如果我们分析了它,它们都是顺序扫描,因为有5小行]

    简单地说,“seq scan”没有使用索引(通常较慢)所有其他扫描都试图使用表中定义的索引。或者位图扫描也可以是索引扫描的子集。@derobert,“查找”是什么意思?在任何地方都找不到它的任何提及…@Zapadlo在磁盘搜索中搜索,例如,随机访问而不是顺序访问。Postgresql位图堆扫描不会恢复为随机访问。位图是要扫描的一组物理位置,位图堆扫描将按物理位置的排序顺序扫描这些位置。另外,位图引用的每个页面在扫描中只会访问一次。
    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)