2. postgresql并行扫描(1)——pg强制走并行扫描建表及参数配置

转载自:https://developer.aliyun.com/article/700370

1. 参数设置

1.1 postgresql.conf中修改

# 1、总的可开启的WORKER足够大  
max_worker_processes =128

# 2、所有会话同时执行并行计算的并行度足够大  
max_parallel_workers=64

# 3、单个QUERY中并行计算NODE开启的WORKER=24  
max_parallel_workers_per_gather =24
  
# 4、所有表和索引扫描允许并行  
set min_parallel_table_scan_size =0
set min_parallel_index_scan_size =0
  
# 5、并行计算优化器成本设置为0  
set parallel_tuple_cost =0
set parallel_setup_cost =0

1.2 执行前修改

# 1、总的可开启的WORKER足够大  
postgres=# show max_worker_processes ;  
 max_worker_processes   
----------------------  
 128  
(1 row)  
  
# 2、所有会话同时执行并行计算的并行度足够大  
postgres=# set max_parallel_workers=64;  
SET  
  
# 3、单个QUERY中并行计算NODE开启的WORKER=16  
postgres=# set max_parallel_workers_per_gather =16;  
SET  
  
# 4、所有表和索引扫描允许并行  
postgres=# set min_parallel_table_scan_size =0;  
SET  
postgres=# set min_parallel_index_scan_size =0;  
SET  
  
# 5、并行计算优化器成本设置为0  
postgres=# set parallel_tuple_cost =0;  
SET  
postgres=# set parallel_setup_cost =0;  
SET  

# 6、设置表级并行度为2  
postgres=# alter table test set (parallel_workers =2);  
ALTER TABLE  

# 7、执行结果
test=# explain (analyze) select count(*) from test;
                                                           QUERY PLAN                                                       
    
----------------------------------------------------------------------------------------------------------------------------
----
 Finalize Aggregate  (cost=107.10..107.11 rows=1 width=8) (actual time=13.974..15.860 rows=1 loops=1)
   ->  Gather  (cost=107.08..107.09 rows=2 width=8) (actual time=9.101..15.841 rows=3 loops=1)
         Workers Planned: 2
         Workers Launched: 2
         ->  Partial Aggregate  (cost=107.08..107.09 rows=1 width=8) (actual time=2.609..2.610 rows=1 loops=3)
               ->  Parallel Seq Scan on test  (cost=0.00..96.67 rows=4167 width=0) (actual time=0.026..1.645 rows=3333 loops
=3)
 Planning Time: 1.899 ms
 Execution Time: 16.046 ms
(8 rows)

max_parallel_workers_per_gather 参数控制执行节点的最大并行进程数,通过以上并行计划可知,开启并行后,会启动两个 worker 进程(即 Workers Launched: 2)并行执行

2. 建表

drop table test;
create table test(a int, b int, c int);
create index ii on test(b);
insert into test valuers(generate_series(1, 10000), generate_series(1, 10000), generate_series(1, 10000);
analyze test;
vacuum full test;

3. pg并行概述参考连接

https://developer.aliyun.com/article/684431

并行扫描的理念很朴素,即启动多个 worker 并行扫描表中的数据。以前一个进程做所有的事情,无人争抢,也无需配合,如今多个 worker 并行扫描,首先需要解决如何分工的问题。

PostgreSQL 中的并行扫描分配策略也很直观,即 block-by-block。多个进程间(leader 和 worker)维护一个全局指针 next,指向下一个需要扫描的 block,一旦某个进程需要获取一个 block,则访问该指针,获取 block 并将指针向前移动。

目前支持并行的常用扫描算子有:SeqScan,IndexScan,BitmapHeapScan 以及 IndexOnlyScan。

下图分别是并行 SeqScan(左)和 并行 IndexScan(右)的原理示意图,可见两者均维护一个 next 指针,不同的是 SeqScan 指向下一个需要扫描的 block,而 IndexScan 指向下一个索引叶子节点。

注意,目前并行 IndexScan 仅支持 B-tree 索引。
2. postgresql并行扫描(1)——pg强制走并行扫描建表及参数配置_第1张图片
并行 IndexOnlyScan 的原理类似,只是无需根据索引页去查询数据页,从索引页中即可获取到需要的数据;并行 BitmapHeapScan 同样维护一个 next 指针,从下层 BitmapIndexScan 节点构成的位图中依次分配需要扫描的 block。

个人理解:这里实现并行的核心主要是多个线程如何处理这个全局的next指针。

后续计划对这部分的源码进行单步调试进行原理的学习。

你可能感兴趣的:(postgresql,数据库)