当前位置: 首页 > article >正文

PG的并行查询

PG学习笔记

PostgreSQL利用多CPU 让查询更快,这种特性被称为并行查询。

并行执行的优势

postgres=# explain analyze select count(*) from t3;
                                                                 QUERY PLAN                                                                  
---------------------------------------------------------------------------------------------------------------------------------------------
 Finalize Aggregate  (cost=964311.71..964311.72 rows=1 width=8) (actual time=13581.820..13583.875 rows=1 loops=1)
   ->  Gather  (cost=964311.50..964311.71 rows=2 width=8) (actual time=13567.259..13583.845 rows=3 loops=1)
         Workers Planned: 2
         Workers Launched: 2
         ->  Partial Aggregate  (cost=963311.50..963311.51 rows=1 width=8) (actual time=13559.285..13559.287 rows=1 loops=3)
               ->  Parallel Seq Scan on t3  (cost=0.00..859144.80 rows=41666680 width=0) (actual time=0.036..9740.796 rows=33333333 loops=3)
 Planning Time: 3.170 ms
 Execution Time: 13583.996 ms
(8 rows)

postgres=# set max_parallel_workers_per_gather =0;
SET
postgres=# explain analyze select count(*) from t3;
                                                        QUERY PLAN                                                         
---------------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=1692478.40..1692478.41 rows=1 width=8) (actual time=14258.661..14258.661 rows=1 loops=1)
   ->  Seq Scan on t3  (cost=0.00..1442478.32 rows=100000032 width=0) (actual time=0.012..9640.810 rows=100000000 loops=1)
 Planning Time: 0.038 ms
 Execution Time: 14258.685 ms
(4 rows)


第一个sql进行了并行查询,Gather节点位于最顶端,说明整个查询都是并行,如果Gather或Gather Merge位于Plan Tree的中间层,则位于Plan Tree下方的都是并行。第二个sql关闭了并行,在有缓存的情况下,执行依然比第一个并行执行的sql还要慢一些。

并行成本值

postgres=# show parallel_setup_cost ;
 parallel_setup_cost 
---------------------
 1000
(1 row)

postgres=# show parallel_tuple_cost ;
 parallel_tuple_cost 
---------------------
 0.1
(1 row)

并行执行需要的条件

(1)需要动态共享内存DSM

并行执行,需要将多个worker进程结果进行汇总,通信,因此需要一个共享内存。
DSM是Dynamic Shared Memory即动态共享内存。动态共享内存不需要系统启动时预先分配,在执行时动态创建,用于leader与worker间的通信,执行完成后释放。

postgres=# show dynamic_shared_memory_type ;
 dynamic_shared_memory_type 
----------------------------
 posix
(1 row)

DSM的位置如下:posix模式下,使用的是tmpfs 位置在/dev/shm

**执行watch -n 1 ls /dev/shm/ 再psql中执行并行查询,可以看到此目录下的文件增删的情况。**如果这个目录满了,会报错

[root@VM-20-8-centos ~]# df -h
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        989M     0  989M   0% /dev
tmpfs          1000M  1.3M  999M   1% /dev/shm
tmpfs          1000M  552K  999M   1% /run
tmpfs          1000M     0 1000M   0% /sys/fs/cgroup
/dev/vda1        50G  8.5G   39G  18% /
tmpfs           200M     0  200M   0% /run/user/0

如果主机内存不够,可以将type改为mmap模式,使用文件的方式存储。

postgres=# select name,enumvals from pg_settings where name ='dynamic_shared_memory_type';
            name            |     enumvals      
----------------------------+-------------------
 dynamic_shared_memory_type | {posix,sysv,mmap}
(1 row)


(2)参数限制

min_parallel_index_scan_size和min_parallel_table_scan_size是使用并行扫描的最小表大小和索引大小的条件。

show min_parallel_index_scan_size ;
 min_parallel_index_scan_size 
------------------------------
 512kB
(1 row)


postgres=# show min_parallel_table_scan_size;
 min_parallel_table_scan_size 
------------------------------
 8MB
(1 row)

并行的参数

max_parallel_workers
设置系统支持的并行查询进程数。不过得小于max_worker_processes的值,因为并行worker是从该max_worker_processes建立的worker进程池中获取的。

parallel_workers
是一个表级的参数,和fillfactor等类似,很容易被忽略,该参数表示表级并行度,指定对表扫描可以启用的工作进程数,默认不设置,依据表的大小计算出一个值,alter table test set (parallel_workers =32);

max_parallel_workers_per_gather
控制一个并行的EXEC NODE最多能开启多少个并行worker,也就是单个Gather节点的并行度。

force_parallel_mode
表示强制开启并行,可以用来模仿Oracle的Hint。

parallel_leader_participation leader是否参与worker的工作。设置为off可以减少工作进程被阻塞的几率

如下设置max_parallel_workers_per_gather为8,则使用了6个并行

postgres=# show max_parallel_workers_per_gather ;
 max_parallel_workers_per_gather 
---------------------------------
 8
(1 row)

postgres=# explain analyze select count(*) from t3;
                                                                 QUERY PLAN       
                                                           
----------------------------------------------------------------------------------
-----------------------------------------------------------
 Finalize Aggregate  (cost=651812.03..651812.04 rows=1 width=8) (actual time=12371
.659..12371.809 rows=1 loops=1)
   ->  Gather  (cost=651811.40..651812.01 rows=6 width=8) (actual time=12363.417..
12371.792 rows=7 loops=1)
         Workers Planned: 6
         Workers Launched: 6
         ->  Partial Aggregate  (cost=650811.40..650811.41 rows=1 width=8) (actual
 time=12347.425..12347.426 rows=1 loops=7)
               ->  Parallel Seq Scan on t3  (cost=0.00..609144.72 rows=16666672 wi
dth=0) (actual time=0.029..9900.161 rows=14285714 loops=7)
 Planning Time: 0.038 ms
 Execution Time: 12371.836 ms
(8 rows)


http://www.kler.cn/a/406123.html

相关文章:

  • ubuntu20.04的arduino+MU编辑器安装教程
  • 为啥需要MD5加密的时候用str(i)而不是“i”
  • Jmeter数据库压测之达梦数据库的配置方法
  • PostGIS分区表创建
  • 【从零开始的LeetCode-算法】3233. 统计不是特殊数字的数字数量
  • 自由学习记录(23)
  • 亲测解决Unpack operator in subscript requires Python 3.11 or newer
  • 本地可运行,jar包运行错误【解决实例】:通过IDEA的maven package打包多模块项目
  • java基础---反射
  • 综合练习--轮播图
  • ubuntu20.04中编译安装gcc 9.2.0
  • .net将List<实体1>的数据转到List<实体2>
  • Linux 常用命令大汇总
  • 【数论】莫比乌斯函数及其反演
  • 探索免费的Figma中文版:开启高效设计之旅
  • tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), PORT)); 解析
  • (超级详细!!!)解决“com.mysql.jdbc.Driver is deprecated”警告:详解与优化
  • xxl-job入门
  • 支持多种快充协议和支持多种功能的诱骗取电协议芯片
  • 解决——CPN IDE卡在启动画面中 initializing状态
  • 二、CSS
  • tcp/ip异常断开调试笔记——lwip
  • Android音频采集
  • C# NetworkStream用法
  • 我对软考“背背背”的看法
  • [已解决]Tomcat 9.0.97控制台乱码