PG-并行查询

并行查询
并行查询引入新节点
  • Gather:并行执行子计划的结果向上层节点输出,不保证有序

  • GatherMerge:并行执行子计划的结果向上层节点有序输出

并行相关参数
参数 描述
max_work_processer(integer) 设置系统支持的最大后台进程,默认值为8,此参数调整后需要重启数据库才生效。备库需要大于主库
max_parallel_workers(integer) 系统并行查询进程,默认值为8。其值不超过max_work_processer
max_parallel_workers_per_gather(integer) 运行启用并行进程的进程数,默认值2。设置成0则禁用并行查询。
parallel_setup_cost(floating point) 优化器启动并行进程的成本,默认为1000
parallel_tuple_cost(floating point) 设置优化器通过并行进程处理一行数据的成本,默认是0.1
min_parallel_table_scan_size(integer) 设置开启并行的条件之一,表占用空间小于此值将不会开启并行,并行顺序扫描场景下扫描的数据大小通常等于表大小,默认值8MB
min_parallel_index_scan_size(integer) 设置开启并行的条件之一,实际上并行扫描不会扫描索引所有数据块,只是扫描索引相关数据块,默认值512kb
force_parallel_model(num) 强制开启并行,OLTP生产环境开启需要慎重,不建议开启
select name,setting,unit,enumvals,vartype
  from pg_settings ps
 where 1=1
   and ps.name in (
         'force_parallel_mode',
         'max_worker_processes',
         'max_parallel_workers',
         'max_parallel_maintenance_workers',
         'max_parallel_workers_per_gather',
         --'min_parallel_relation_size',-- add 9.6,remove from 10
         'min_parallel_index_scan_size',
         'min_parallel_table_scan_size',
         'parallel_tuple_cost',
         'parallel_setup_cost',
         'parallel_leader_participation'
)
;
  • max_parallel_workers_per_gather :每个 Gather/GatherMerge 最大的并行 worker 数(不包含 leader),默认值为2

image-20211014151830765

  • min_parallel_table_scan_size : 使用并行扫描的最小表大小,默认 8MB
  • min_parallel_index_scan_size : 使用并行扫描的最小索引大小,默认 512KB

image-20211014153959330

并行计划示意图

image-20211014152127772

并行查询计划中,处理用户请求的 backend 进程称之为主进程(leader),将执行时动态生成的进程称之为工作进程(worker)。每个 worker 执行 Gather 节点以下计划的一个副本,leader 节点主要负责处理 Gather 及其以上节点的操作,根据 worker 数不同,leader 也可能会执行 Gather 以下计划的副本。

并行查询中引入了两个新的代价值
  • parallel_tuple_cost : 每个 Tuple 从 worker 传递给 master 的代价,即 worker 将一个 tuple 放入共享内存队列,然后 master 从中读取的代价,默认值为 0.1
  • parallel_setup_cost : 启动并行查询 worker 进程的代价,默认值为 1000
示例
-- 创建表
CREATE TABLE t_big(
	id int4,
	name character varying(32),
	create_time timestamp without time zone DEFAULT clock_timestamp()
);
-- 插入数据
INSERT INTO t_big(id,name)
SELECT n, n||'_tv' FROM generate_series(1,5000000) n;
-- 一个并行顺序扫描的执行计划
EXPLAIN ANALYSE SELECT * FROM t_big WHERE name = '1_tv';

-- 创建索引
create index id_t_big_name on t_big using btree (name); 

image-20211014160410044

  • Workers Planned :执行计划预估的并行进程数
  • Workers Launched: 查询实际获得的并行进程数。
  • Parallel Seq Scan on t_big :并行顺序(全表)扫描
  • Planning time :生成执行计划的时间
  • Execution time :SQL实际执行时间
posted @ 2021-10-15 21:33  KuBee  阅读(369)  评论(0编辑  收藏  举报