PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Qual è la differenza tra Seq Scan e Bitmap heap scan in Postgres?

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

Fondamentalmente, una scansione sequenziale passa alle righe effettive e inizia a leggere dalla riga 1 e continua fino a quando la query non è soddisfatta (questa potrebbe non essere l'intera tabella, ad esempio, nel caso del limite)

La scansione dell'heap bitmap significa che PostgreSQL ha trovato un piccolo sottoinsieme di righe da recuperare (ad esempio, da un indice) e recupererà solo quelle righe. Questo ovviamente avrà molte più ricerche, quindi è più veloce solo quando ha bisogno di un piccolo sottoinsieme di righe.

Prendi un esempio:

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);

Ora possiamo facilmente ottenere una scansione sequenziale:

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)

Ha eseguito una scansione sequenziale perché stima che occuperà la stragrande maggioranza del tavolo; cercare di farlo (invece di una grande lettura senza ricerca) sarebbe sciocco.

Ora possiamo usare l'indice:

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)

E infine, possiamo ottenere alcune operazioni bitmap:

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)

Possiamo leggere questo come:

  1. Costruisci una bitmap delle righe che vogliamo per a=4. (Scansione dell'indice bitmap)
  2. Costruisci una bitmap delle righe che vogliamo per a=3. (Scansione dell'indice bitmap)
  3. O le due bitmap insieme (BitmapOr)
  4. Cerca quelle righe nella tabella (scansione heap bitmap) e assicurati che a=4 o a=3 (ricontrolla cond)

[Sì, questi piani di query sono stupidi, ma è perché non siamo riusciti ad analizzare test Se lo avessimo analizzato, sarebbero state tutte scansioni sequenziali, dato che ci sono 5 righe minuscole]