如何加快分区表上的服务器端聚合

问题描述 投票:1回答:1

背景

我正在使用3 * 10 ^ 9行的RDS上的Postgres 10.6中的标准化分区表生成Tukey盒须图。

我已经开始连续使用多个视图,包括聚合步骤和随后的异常值检测步骤。首先,在聚合步骤中,我计算中值,25%,75%,IQR,(25% - 1.5 * IQR)较低的晶须和(75%+ 1.5 * IQR)上晶须。其次,在离群检测步骤中,我在表格中搜索位于胡须外的值。

聚合

create view aggregation as
select
    a.a_name,
    b.b_name,
    c.c_name,
    percentile_cont(0.5) within group (order by d.D) as median,
    etc for 75%, IQR, whiskers
from dtable as d
join atable as a on a.a_id = d.a_id
join etable as e on e.e_id = d.e_id
join ftable as f on f.f_id = e.f_id
join btable as b on b.b_id = f.b_id
join ctable as c on c.c_id = b.c_id
where (d.e_id between 3440500 and 3459500)
and (c.c_name = 'this_c_in_particular')
and (b.b_name in ('first_b', 'second_b', 'third_b'))
group by
a.a_name,
b.b_name,
c.c_name
;

请注意,dtablee_id分区

异常值检测

create view outliers as
select d.*
from dtable as d
join atable, etable, ftable, btable, ctable
join aggregation as agg on
    agg.a_name = atable.a_name,
    agg.b_name = btable.b_name,
    agg.c_name = ctable.c_name
where d.value < agg.lower_whisker or d.value > agg.upper_whisker
;

结果

目前,使用平面客户端pandas数据帧,我可以在网络传输和服务器端下采样后的10秒内执行这些聚合。但是,在客户端,这些聚合至少需要1分钟才能运行。

(EXPLAIN ANALYZE)计划可在此处获取:https://explain.depesz.com/s/0gAu

  1. 是否有快速计算这些聚合的标准方法?
  2. 有没有办法让Postgres并行计算这些东西,每组1个工人?

任何见解或讨论都非常受欢迎 - 感谢阅读。

postgresql aggregate partitioning query-performance
1个回答
2
投票

执行计划有一些我不明白的事情:

  • 如果没有计划并行工作人员,为什么会有Gather节点?从loops我预计会有两名工人。
  • 为什么expain.depesz.com不计算底部节点的895693次迭代(也许它和上面的我一样困惑)?

尽管如此,可以立即发现一些问题:

  • 有可怕的错误估计(725而不是895693实际行!)。
  • 您的大部分时间都花费在溢出到磁盘的排序上。

所以这里是你可以改进而不重写查询:

  • 增加work_mem直到排序是quicksort memory。这应该是最大的收获。 你不必全局增加它,你可以运行如下: BEGIN; SET LOCAL work_mem = '1GB'; SELECT /* your query */; COMMIT;
  • 有些表似乎有陈旧的统计数据。尝试ANALYZE有问题的所有表,也许这确实有点好。
  • 你可以通过避免不受指导的嵌套循环连接来刮掉几秒钟。也许ANALYZE会照顾到这一点。 作为最后的手段,您可以简单地为该查询禁用嵌套循环,方法是为一个查询设置enable_nestloop = off,使用与上面针对work_mem相同的技巧。

分区表上的扫描不是您的问题,因此您不必担心并行化(PostgreSQL v11已变得更加智能)。

如果以上所有方法都不能使查询足够快,您可以考虑使用物化视图。然后你得到稍微陈旧的数据,但速度很快。

© www.soinside.com 2019 - 2024. All rights reserved.