写点什么

解析数仓 lazyagg 查询重写优化规则

  • 2022 年 5 月 28 日
  • 本文字数:2020 字

    阅读完需:约 7 分钟

本文分享自华为云社区《GaussDB(DWS) lazyagg查询重写优化解析【这次高斯不是数学家】》,作者: OreoreO 。


聚集操作将查询结果按某一列或多列的值分组,值相等的为一组。聚集操作是一种常见的操作并在金融客户中有广泛的使用。例如如下语句则聚集操作将查询结果按某一列或多列的值分组,值相等的为一组。聚集操作是一种常见的操作并在金融客户中有广泛的使用。例如如下语句 eze 聚集操作将查询结果按某一列或多列的值分组,值相等的为一组。聚集操作是一种常见的操作并在金融客户中有广泛的使用。例如如下语句则聚集操作将查询结果按某一列或多列的值分组,值相等的为一组。聚集操作是一种常见的操作并在金融客户中有广泛的使用。例如如下语句:


SELECT a, count(a) FROM t1 GROUP BY a; -- 按a分组并计算分组内重复值的个数复制代码
复制代码

一、Lazy Agg 重写规则


数据量大的场景下,聚集运算由于数据量大导致下盘,聚集操作执行时间成为性能瓶颈,从而导致整个查询执行效率非常差。例如:


SELECT t2.b, sum(cc) FROM (SELECT b, sum(c) AS cc FROM t1 GROUP BY b) AS s, t2 WHERE s.b=t2.b GROUP BY t2.b;复制代码
复制代码


子查询对 t1.b 列进行聚集,对 t1.c 列求和,在外部查询中,同样也存在聚集运算,对子查询的聚集求和列 cc 列求和。对于这类语句,当子查询的聚集运算较耗时的情况下,可以利用查询重写规则消除子查询的聚集运算,由外部查询的聚集函数统一完成聚集运算。消除子查询后可能导致子查询行数增多,但对于子查询聚集运算时 t1.b 列的 distinct 值较多的场景,子查询聚集运算后的行数较原表不会有明显缩减,不会导致外层 JOIN 运算量的大量增加。即语句可被重写为:


SELECT t2.b, sum(cc) FROM (SELECT b, c AS cc FROM t1) AS s, t2 WHERE s.b=t2.b GROUP BY t2.b;复制代码
复制代码


这个改写规则称为 Lazy Agg,适用于基表数据量大且 distinct 值较多的场景。如果重复值较少,那么消除了聚集操作会导致 Join 后的行数激增,Join 性能较差,因此需要将 Agg 下推到 Join 之前进行,通过提前的 Agg 操作减少 Join 结果的行数,这个改写规则称为 Eager Agg。

二、GaussDB(DWS) lazyagg 优化


为了降低调优难度,提升产品易用性,GaussDB(DWS)提供了 lazyagg 查询重写优化规则,可以通过设置 guc 参数 rewrite_rule 包含’lazyagg’使用 Lazy Agg 查询重写优化。开启 lazyagg 查询重写优化后,对满足条件的场景会优化并消除子查询中的聚集操作。原计划如下所示:



lazyagg 重写优化后计划如下所示:



可以看到相比于原计划,lazyagg 重写优化后消除掉了原计划中的聚集操作,即 7 号 Subquery Scan 算子和 8 号 HashAggregate 算子。

三、lazyagg 优化规格


1. 支持子查询为单一聚集查询或包含聚集子集合操作的查询。集合操作仅支持 UNION ALL,可对部分分支子查询进行聚集运算消除。子查询需为 JOIN 表之一(不在 TargetList、Where 子句等其他位置)。


2. 支持若外部查询的所有 Agg 参数列包含于其某个子查询的 Agg 函数列,则可对该子查询的聚集运算进行消除。


3. 支持所有消除子查询聚集运算后结果正确的聚集函数种类。聚集函数种类结果正确性见下表:



4. 场景约束


在上述场景扩展的基础上,对于可能导致结果错误的场景,不进行查询重写,包括但不限于:


· 不支持消除的 Agg 函数类型。


· 子查询中包含其它条件或算子,会导致重写后结果错误,例如 HAVING、window agg、LIMIT、OFFSET、AP function、distinct、recursive 等。


· 外层 Agg 参数列、GROUP BY 列或 JOIN 列中包含 volatile 函数,如 random、timeofday 等。


· 子查询 Agg 函数外、外部查询 Agg 函数内有其他表达式或函数操作,如子查询 Agg 函数列为 sum©+1、max©+max(d),外部查询 Agg 函数列为 sum(cc+1)等。


· 外部查询的 JOIN 列、GROUP BY 列或其它条件中包含子查询 Agg 函数列。


· 子查询在 LEFT JOIN、RIGHT JOIN 的 inner 边或 FULL JOIN 中,且子查询 Agg 函数为 count,外部查询 Agg 函数为 sum 的。

四、结语


通过本文的分析,相信用户朋友已经充分了解了 Lazy Agg 重写优化的使用场景,以及 GaussDB(DWS)的 lazyagg 实现方式。希望广大用户能够通过深入的了解,对 GaussDB(DWS)的性能调优产生浓厚的兴趣并深度参与进来。


参考文档:GaussDB(DWS)性能调优系列实战篇四:十八般武艺之SQL改写

理论不如实践,那如何快速体验 DWS 呢?DWS 现推出了一项 Demo 体验活动。进入DWS首页,点击“Demo体验”,快速便捷体验一把!

体验过程中有任何建议和意见,可以去DWS社区论坛反馈哦;)

【这次高斯不是数学家】有奖征文火热进行中:bbs.huaweicloud.com/blogs/34526…


华为伙伴暨开发者大会 2022 火热来袭,重磅内容不容错过!


精彩活动】勇往直前·做全能开发者→12 场技术直播前瞻,8 大技术宝典高能输出,还有代码密室、知识竞赛等多轮神秘任务等你来挑战。即刻闯关,开启终极大奖!点击【勇往直前】踏上全能开发者晋级之路吧!


技术专题】未来已来,2022 技术探秘→华为各领域的前沿技术、重磅开源项目、创新的应用实践,站在智能世界的入口,探索未来如何照进现实,干货满满 点击了解


​​点击关注,第一时间了解华为云新鲜技术~

发布于: 刚刚阅读数: 4
用户头像

提供全面深入的云计算技术干货 2020.07.14 加入

华为云开发者社区,提供全面深入的云计算前景分析、丰富的技术干货、程序样例,分享华为云前沿资讯动态,方便开发者快速成长与发展,欢迎提问、互动,多方位了解云计算! 传送门:https://bbs.huaweicloud.com/

评论

发布
暂无评论
解析数仓lazyagg查询重写优化规则_数据库_华为云开发者社区_InfoQ写作社区