本节介绍了PostgreSQL中数据表的三种扫描类型,分别是顺序扫描SeqScan、索引扫描IndexScan和位图堆扫描BitmapHeapScan。
一、简介
选择率=条件过滤后的元组数/条件过滤前的元组数
顺序扫描SeqScan
直接对数据表堆数据(Heap Data)进行顺序扫描,适用于选择率较高的场景.
索引扫描IndexScan
通过访问索引获得元组位置指针后再访问堆数据,适用于选择率较低的场景.
位图堆扫描BitmapHeapScan
位图堆扫描需要首先通过BitmapIndexScan(位图索引扫描)把符合条件的元组所在的Page(Block) ID存储在Bitmap中,然后再通过Bitmap访问堆数据,适用于选择率不高不低的场景,介于上面两种扫描方式之间.
2018.10.01 修正,索引适用于选择率低的情况,顺序扫描适用于选择率高的情况
值得注意的地方:
1."选择率较高"是一种定性的表述,实际上PG是根据Cost计算来确定使用哪种扫描方式.通常情况下,索引扫描主要执行的操作是随机访问存储设备,在PG的初始化参数配置中,随机访问的Cost是4,而顺序访问的Cost是1,很粗略的估算,如果通过索引访问的Index Blocks + Heap Blocks超过顺序访问的Heap Blocks的1/4,那么PG会选择使用顺序扫描而不是索引扫描.
2.IndexScan的扫描方式是访问索引,如符合条件则马上根据索引中的元组位置指针访问堆数据从而获取元组,而BitmapIndexScan(位图索引扫描)是访问索引,把符合条件的Block ID存储在Bitmap中,这时候不涉及扫描堆数据,最终获取元组的操作通过BitmapHeapScan扫描完成.
这两者的不同,下面这段话总结得非常到位:
A plain Index Scan fetches one tuple-pointer at a time from the index, and immediately visits that tuple in the table. A bitmap scan fetches all the tuple-pointers from the index in one go, sorts them using an in-memory "bitmap" data structure, and then visits the table tuples in physical tuple-location order.
下面通过样例脚本直观感受这几种方式的不同.
测试数据表,t_dwxx,10000行数据,在dwbh上创建PK
testdb=# select count(*) from t_dwxx;
count
-------
10000
(1 row)
二、SeqScan
测试脚本:
testdb=# explain verbose select t1.* from t_dwxx t1 where dwbh > '1000';
QUERY PLAN
----------------------------------------------------------------------
Seq Scan on public.t_dwxx t1 (cost=0.00..189.00 rows=9999 width=20)
Output: dwmc, dwbh, dwdz
Filter: ((t1.dwbh)::text > '1000'::text)
(3 rows)
查询条件为dwbh > '1000',选择率较低,PG选择了顺序扫描SeqScan,成本189.00,该成本如何计算,有兴趣的可参照源码解读(53),通过gdb跟踪分析.
三、IndexScan
测试脚本:
testdb=# explain verbose select t1.* from t_dwxx t1 where dwbh = '10000';
QUERY PLAN
-------------------------------------------------------------------------------------
Index Scan using t_dwxx_pkey on public.t_dwxx t1 (cost=0.29..8.30 rows=1 width=20)
Output: dwmc, dwbh, dwdz
Index Cond: ((t1.dwbh)::text = '10000'::text)
(3 rows)
查询条件为dwbh = '10000',选择率很高,只有1条记录,选择索引扫描.
总成本8.30=启动成本 + 一次Index Block访问 + 一次Heap Block访问=0.29 + 4 + 4≈8.30
四、BitmapHeapScan
测试脚本:
testdb=# explain verbose select t1.* from t_dwxx t1 where dwbh > '1000' and dwbh < '3000';
QUERY PLAN
---------------------------------------------------------------------------------------------
Bitmap Heap Scan on public.t_dwxx t1 (cost=51.07..148.42 rows=2223 width=20)
Output: dwmc, dwbh, dwdz
Recheck Cond: (((t1.dwbh)::text > '1000'::text) AND ((t1.dwbh)::text < '3000'::text))
-> Bitmap Index Scan on t_dwxx_pkey (cost=0.00..50.52 rows=2223 width=0)
Index Cond: (((t1.dwbh)::text > '1000'::text) AND ((t1.dwbh)::text < '3000'::text))
(5 rows)
查询条件为dwbh > '1000' and dwbh < '3000',选择率不高不低,PG选择了BitmapHeapScan,启动成本为51.07,总成本为148.42,该成本如何计算,后续的源码解读会跟踪分析.
值得注意的是在BitmapIndexScan后有一步:Recheck,这是因为位图索引扫描只是把Heap Block ID找出来,并没有把符合条件的元组找出来,因此出现了Recheck这一步.
五、参考资料
PostgreSQL indexing: Index scan vs. Bitmap scan vs. Sequential scan
Bitmap indexes
What is a “Bitmap heap scan” in a query plan?
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
软考中级精品资料免费领
- 历年真题答案解析
- 备考技巧名师总结
- 高频考点精准押题
- 资料下载
- 历年真题
193.9 KB下载数265
191.63 KB下载数245
143.91 KB下载数1148
183.71 KB下载数642
644.84 KB下载数2756