ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

PG的并行查询生产案例

2022-06-22 16:31:55  阅读:161  来源: 互联网

标签:name 并行 workers gather worker 查询 PG max parallel


1.背景:

开发想通过web前端调用sql获取数据展现在内部平台上,发现查询较慢。

2.SQL分析:

PG环境

 

pg_tables=# select version();
version
----------------------------------------------------------------------------------------------------------------------------------------
PostgreSQL 12.11 (Ubuntu 12.11-0ubuntu0.20.04.1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0, 64-bit
(1 row)

 

我拿来SQL直接贴下

EXPLAIN

SELECT
platform_name,
tid,
company_name_bill,
company_name_order,
shop_code_bill,
platform_code_bill,
shop_code_order,
platform_code_order,
brand_cn,
prosy_type,
category,
shop_name_bill,
shop_name_order,
status,
created,
pay_time,
consign_time,
sku_new,
product_id,
title,
sku_qy,
sales_price,
total_payment,
cost_to,
COST,
cost_sum,
sales_sum,
gross_profit,
gross_margin,
pay_no,
tracking_no,
logistics_company,
receiver_name,
receiver_address,
receiver_mobile,
buyer_nick,
is_refundamount,
expend_amount,
created_ex,
is_amount,
income_amount,
currency,
exchange_rate,
overseas_income,
overseas_expend,
is_overseas,
overseas_income_hkd,
overseas_expend_hkd,
created_in,
trading_channels,
currency_cny_rate,
post_fee,
up_time,
ts
FROM
cn_dw_tables.dw_order_info_detail_report_n
WHERE
company_name_bill = 'XXXXXX有限公司'
AND created_in BETWEEN '2022-03-26'
AND '2022-03-26'
AND platform_code_bill = 'xxxxxx'
AND shop_name_bill = 'XXXXXXX'
AND sku_new = 'xxxxxxxxx'
AND ts BETWEEN '2022-03'
AND '2022-03'
ORDER BY
created_in,pay_time DESC
LIMIT 100   发现基于ts字段进行了list分区。

去掉explain,查询花费了近3.891秒。

 

 

 

 

 3.因为表的ts字段基于list分区,因为这台PG主要用于BI数据分析和审计或测试等作用,和使用人沟通暂时不能通过加索引方式解决,会影响其它报表dml使用。

 经过explain分析,发现并行顺序扫描只有2个worker.

 

4.看下cpu核数(40核,说明下这台是台40核200G内存的dell物理机,在上面做了虚拟化,所以wokers planned也不能设置太高)

#cat /proc/cpuinfo |grep processor
processor : 0
processor : 1
processor : 2
processor : 3
processor : 4
processor : 5
processor : 6
processor : 7
processor : 8
processor : 9
processor : 10
processor : 11
processor : 12
processor : 13
processor : 14
processor : 15
processor : 16
processor : 17
processor : 18
processor : 19
processor : 20
processor : 21
processor : 22
processor : 23
processor : 24
processor : 25
processor : 26
processor : 27
processor : 28
processor : 29
processor : 30
processor : 31
processor : 32
processor : 33
processor : 34
processor : 35
processor : 36
processor : 37
processor : 38
processor : 39

 #########查询配置中max_parallel_workers_per_gather大小

pg_tables=# show max_parallel_workers_per_gather;
max_parallel_workers_per_gather
---------------------------------
2
(1 row)

 

###增加worker数量为8

pg_tables=# alter system set max_parallel_workers_per_gather=8;
ALTER SYSTEM
pg_tables=# select * from pg_reload_conf();
pg_reload_conf
----------------
t
(1 row)

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

 

 

再查发现只要1.81秒,over,大功告成!

 

 

4.原因分析:

Parallel Seq Scan”节点生成用于部分聚合的行。“Partial Aggregate”节点使用 SUM() 减少这些行。最后,每个worker进程的SUM计数器由“Gather”节点收集。 最终结果由“Finalize Aggregate”节点计算。

结合where条件,从数据页中逐个读取行不是因为并行读取;与普通的单线程选择相比,更复杂的查询速度提高了若干倍。

 

5.worker设置多大为好:

这个问题可以参考percona https://www.percona.com/blog/2019/02/21/parallel-queries-in-postgresql/

首先,max_parallel_workers_per_gather参数是worker数量的最小限制。其次,查询执行程序从max_parallel_workers大小限制的池中获取worker。最后,最顶层的限制是max_worker_processes,它用来限制后台进程的总数。 工作分配失败会导致单进程执行。 查询计划可以根据表或索引大小减少worker数。min_parallel_table_scan_sizemin_parallel_index_scan_size控制这一行为。

set min_parallel_table_scan_size='8MB'
8MB table => 1 worker
24MB table => 2 workers
72MB table => 3 workers
x => log(x / min_parallel_table_scan_size) / log(3) + 1 worker

每次表比minparallel(index | table)scansize大3倍时,postgres会添加一个worker。worker数量不是以cost为基础的!循环依赖使得复杂的实现变得困难。相反,查询规划使用简单的规则。

实际上,这些规则在生产中并不总是可以接受,您可以使用ALTER TABLE ... SET(parallel_workers = N)覆盖特定表的worker数量。

 

标签:name,并行,workers,gather,worker,查询,PG,max,parallel
来源: https://www.cnblogs.com/chinaops/p/16401094.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有