RDS for PG并行查询的一个案例分析

举报
zenith 发表于 2021/04/19 09:01:09 2021/04/19
【摘要】 本文介绍了PG的并行处理的相关参数,并介绍了一个与并行处理相关的一个案例。

近期,有一个客户反馈,他们的一个复杂sql,有时查询需要花费4s,但是有时需要40s,相差十倍之多,请求运维人员定位。

接到反馈之后,对他们的SQL的执行计划进行分析。经过比较快、慢两次的执行计划,发现其执行计划是不一样的,快的时候启用了并行查询,慢的时候是非并行查询

慢的时候:

-> HashAggregate (cost=1998222.44..2089351.51 rows=2603688 width=429)
Group Key: a.book, a.subject, a.currency, a.secorg, a.period
-> Seq Scan on xxxxxx a (cost=0.00..1543730.60 rows=25970962 width=201)
Filter: (((period)::text >= '2020'::text) AND ((period)::text <= '2021-01'::text) AND ((tenantid)::text = 'xxxxx'::text) AND ((accbook)::text = 'xxxxxxxxxxxx::text))
-> Hash (cost=1136.84..1136.84 rows=5884 width=43)
Buckets: 8192 Batches: 1 Memory Usage: 499kB
-> Seq Scan on bd_accsubject y (cost=0.00..1136.84 rows=5884 width=43)

快的时候:

-> HashAggregate (cost=1803124.43..1881116.86 rows=2228355 width=429)
Group Key: a.book, a.subject, a.currency, a.secorg, a.period
-> Gather (cost=1000.00..1741854.47 rows=3501141 width=201)
Workers Planned: 7
-> Parallel Seq Scan on fi_balance a (cost=0.00..1390740.37 rows=500163 width=201)
Filter: (((period)::text >= '2020'::text) AND ((period)::text <= '2021-01'::text) AND ((tenantid)::text = 'xxxxxx'::text) AND ((accbook)::text = 'xxxxxxxxxxxx::text))
-> Hash (cost=1136.84..1136.84 rows=5884 width=43)
-> Seq Scan on bd_accsubject y (cost=0.00..1136.84 rows=5884 width=43)

很明显是因为并行查询带来了速度的提升。但是为什么有时候启用了并行查询 有时却没有呢?

分析和并行查询的有关参数:

force_parallel_mode
允许为测试目的使用并行查询,即便是并不期望在性能上得到效益。 force_parallel_mode的允许值是
off (只在期望改进性能时才使用并行模式)、
on (只要查询被认为是安全的,就强制使用并行查询)以及 regress(和on相似, 但是有如下文所解释的额外行为改变)。
更具体地说,把这个值设置为on 会在任何一个对于并行查询安全的查询计划顶端增加一个 Gather节点,这样查询会在一个并行工作者中运行。
即便当一个并行工作者不可用或者不能被使用时, 诸如开始一个子事务等在并行查询环境中会被禁止的操作将会被禁止, 除非规划器相信这样做会导致查询失败。
当这个选项被设置时如果出现失败或者意料之外的结果, 查询使用的某些函数可能需要被标记为PARALLEL UNSAFE (或者可能是PARALLEL RESTRICTED)。
把这个值设置为regress具有设置成on 所有相同的效果,外加一些有助于自动回归测试的额外的效果。
一般来说, 来自于一个并行工作者的消息会包括一个上下文行指出这一点, 但是设置为regress会消除这一行, 这样输出就和非并行执行完全一样。
同样,被这个设置加到计划上的 Gather节点在EXPLAIN输出终会被隐藏起来, 这样产生的输出匹配设置为off时产生的输出。

max_worker_processes
设置系统能够支持的后台进程的最大数量。这个参数只能在服务器启动时设置。 默认值为 8。
在运行一个后备服务器时,你必须把这个参数设置为等于或者高于主控服务器上的值。否则, 后备服务器上可能不会允许查询。

max_parallel_workers_per_gather
必须被设置为大于零的值。这是一种特殊情况,更加普遍的原则是所用的工作者数量不能超过max_parallel_workers_per_gather所配置的数量。
设置单个Gather节点能够开始的工作者的最大数量。
并行工作者会从max_worker_processes建立的进程池中取得。
注意所要求的工作者数量在运行时可能实际无法被满足。
如果这种事情发生, 该计划将会以比预期更少的工作者运行,这可能会不太高效。
这个值设置为 0(默认值)将会禁用并行查询执行。
注意并行查询可能消耗比非并行查询更多的资源, 因为每一个工作者进程时一个完全独立的进程, 它对系统产生的影响大致和一个额外的用户会话相同。
在为这个设置选择值时, 以及配置其他控制资源利用的设置(例如work_mem)时, 应该把这个因素考虑在内。work_mem 之类的资源限制会被独立地应用于每一个工作者, 这意味着所有进程的总资源利用可能会比单个进程时高得多。
例如, 一个使用 4 个工作者的并行查询使用的 CPU 时间、内存、I/O 带宽可能是不使用工作者时的 5 倍之多。

min_parallel_relation_size
启用并行查询的表的最小值

parallel_tuple_cost
parallel_setup_cost
计算并行处理的成本,如果成本高于非并行,则不会开启并行处理。

经过对这些参数的分析,我们发现parallel_tuple_cost 和 parallel_setup_cost这两个参数比较关键,他们决定了CBO到底要不要启用并行,于是建议用户对这两个参数进行调整,以使得每次都触发并行查询。

参考文献:

https://www.cnblogs.com/ctypyb2002/p/9793035.html

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。