数仓性能调优:row_number() over(p)-rn=1性能瓶颈发现和改写套路_百 ...

发布网友 发布时间:21小时前

我来回答

1个回答

热心网友 时间:20小时前

本文分享自华为云社区《 GaussDB(DWS)性能调优:row_number() over(p)-rn=1性能瓶颈发现和改写套路》,作者:Zawami 。

本套路应用于子查询中含有row_number() over(partition by order by) rn,并仅把rn列用于分类排序后筛选最大值的场景。

GaussDB中SQL语句的执行很多时候是流式的,即对每一条数据进行流水加工,各层算子同时在执行,缩短执行耗时。

然而,在特定情况下,SQL需要先获取前一个算子的全部结果集,才能继续下一步处理。窗口函数是导致这种延迟的常见原因。

在观察执行计划时,我们发现SQL在计算rn列后,需进行与本层其他列的关联。由于存在窗口函数,SQL必须等待51号算子执行完毕,才能进行关联,这造成了性能瓶颈。

通过移除窗口函数,我们可以实现分类汇总与明细数据之间的流水执行。

改写前局部SQL:

改写后局部SQL:

改写解析:首先,我们根据原SQL中row_number() over()的partition列和order列进行数据去重。由于原SQL未定义LIFE_CYCLE的排序方式,改写时我们既可以使用MAX也可以使用MIN函数进行聚合。之后,我们对去重后的数据进行筛选。

使用此修改方法,对比了修改前后的全量执行计划,并在附件中提供。

这种改写方法解决了上层算子等待窗口函数的问题。发现对于不涉及聚合的其他列,如例子中的LIFE_CYCLE,若还需进一步聚合,则本层子查询中的去重并非必要。可进一步去除这层去重。

改写后执行计划如下:

可见,尽管51层算子的执行时间仅缩短了200ms,但减少了阻塞,导致1~7层算子的执行时间大幅缩短,总体执行时间比原先快了约480ms。

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com