postgresql-扫描方式
Pg中支持的扫描方式
- 顺序扫描
- 索引扫描
- 仅索引扫描
- 位图扫描
- tid扫描
试验
建表
postgres=# create table abce(id int, num numeric);
CREATE TABLE
postgres=# create index idx_abce on abce(num);
CREATE INDEX
postgres=# insert into abce select generate_series(1,1000000),random()*1000;
INSERT 0 1000000
postgres=# analyze;
ANALYZE
seq scan
postgres=# explain select * from abce where num < 20000;
QUERY PLAN
---------------------------------------------------------------
Seq Scan on abce (cost=0.00..17990.00 rows=1000000 width=15)
Filter: (num < '20000'::numeric)
(2 rows)
index scan
postgres=# explain select * from abce where num = 20000;
QUERY PLAN
----------------------------------------------------------------------
Index Scan using idx_abce on abce (cost=0.42..8.44 rows=1 width=15)
Index Cond: (num = '20000'::numeric)
(2 rows)
postgres=#
Index Only Scan
postgres=# explain select num from abce where num = 20000;
QUERY PLAN
---------------------------------------------------------------------------
Index Only Scan using idx_abce on abce (cost=0.42..8.44 rows=1 width=11)
Index Cond: (num = '20000'::numeric)
(2 rows)
postgres=#
Bitmap Scan
如果选择少量的行,索引扫描,如果大部分的行,将读取全表;如果对于索引扫描来说读取太多,而顺序扫描来说太少,就会使用位图扫描
原理是扫描过程中,单个块只使用一次。
(1) 位图索引扫描:
首先从索引数据结构中获取所有索引数据,并创建所有TID的位图。为了简单理解,可以认为此位图包含所有页的哈希值(基于page no哈希),每个页面条目包含该页面中所有偏移量的数组。
(2) 位图堆扫描:
顾名思义,它读取页的位图,然后扫描与存储页和偏移量对应的堆中的数据。最后,它检查可见性和谓词等,并根据所有这些检查的结果返回元组。
postgres=# explain select * from abce where num < 200;
QUERY PLAN
-------------------------------------------------------------------------------
Bitmap Heap Scan on abce (cost=5468.94..13430.74 rows=197744 width=15)
Recheck Cond: (num < '200'::numeric)
-> Bitmap Index Scan on idx_abce (cost=0.00..5419.51 rows=197744 width=0)
Index Cond: (num < '200'::numeric)
(4 rows)
Tid Scan
postgres=# select ctid from abce where id=20000;
ctid
-----------
(109,143)
(1 row)
postgres=# explain select * from abce where ctid='(109,143)';
QUERY PLAN
-----------------------------------------------------
Tid Scan on abce (cost=0.00..4.01 rows=1 width=15)
TID Cond: (ctid = '(109,143)'::tid)
(2 rows)
本文来自博客园,作者:{dyy},转载请注明原文链接:{https://www.cnblogs.com/ddlearning/}