详解SQL中Groupings Sets 语句的功能和底层实现逻辑

本文详细介绍了 SQL 中的 Grouping Sets 语句,包括其功能、执行计划和与 Union All 的性能对比。Grouping Sets 提供了一种简化多组聚合的方法,通过 Expand 算子实现。文章还探讨了 RollUp 和 Cube 作为 Grouping Sets 的语法糖,它们在底层实现上与 Grouping Sets 相同,但在 SQL 书写上更为简洁。实验结果显示,Grouping Sets 在性能上优于 Union All。
摘要由CSDN通过智能技术生成

前言

SQL 中  Group By  语句大家都很熟悉, 根据指定的规则对数据进行分组 ,常常和 聚合函数 一起使用。

比如,考虑有表  dealer ,表中数据如下:

如果执行 SQL 语句  SELECT id, sum(quantity) FROM dealer GROUP BY id ORDER BY id ,会得到如下结果:

 +---+-------------+
 | id|sum(quantity)|
 +---+-------------+
 |100|           32|
 |200|           33|
 |300|           13|
 +---+-------------+

上述 SQL 语句的意思就是对数据按  id  列进行分组,然后在每个分组内对  quantity  列进行求和。

Group By  语句除了上面的简单用法之外,还有更高级的用法,常见的是  Grouping Sets 、 RollUp  和  Cube ,它们在 OLAP 时比较常用。其中, RollUp  和  Cube  都是以  Grouping Sets  为基础实现的,因此,弄懂了  ,也就理解了   和   。

本文首先简单介绍  Grouping Sets  的用法,然后以 Spark SQL 作为切入点,深入解析  Grouping Sets  的实现机制。

Spark SQL 是 Apache Spark 大数据处理框架的一个子模块,用来处理结构化信息。它可以将 SQL 语句翻译多个任务在 Spark 集群上执行, 允许用户直接通过 SQL 来处理数据 ,大大提升了易用性。

Grouping Sets 简介

Spark SQL 官方文档中   一节对  Grouping Sets  语句的描述如下:

Groups the rows for each grouping set specified after GROUPING SETS. (... 一些举例) This clause is a shorthand for a  UNION ALL  where each leg of the  UNION ALL  operator performs aggregation of each grouping set specified in the  GROUPING SETS  clause. (... 一些举例)

也即, Grouping Sets  语句的作用是指定几个  grouping set  作为  Group By  的分组规则,然后再将结果联合在一起。它的效果和, 先分别对这些 grouping set 进行  Group By  分组之后,再通过 Union All 将结果联合起来 ,是一样的。

比如,对于  dealer  表, Group By Grouping Sets ((city, car_model), (city), (car_model), ())  和  Union All((Group By city, car_model), (Group By city), (Group By car_model), 全局聚合)  的效果是相同的:

先看 Grouping Sets 版的执行结果:

 spark-sql> SELECT city, car_model, sum(quantity) AS sum FROM dealer 
          > GROUP BY GROUPING SETS ((city, car_model), (city), (car_model), ()) 
          > ORDER BY city, car_model;
 +--------+------------+---+
 |   city|   car_model|sum|
 +--------+------------+---+
 |    null|        null| 78|
 |    null|Honda Accord| 33|
 |    null|   Honda CRV| 10|
 |    null| Honda Civic| 35|
 | Dublin|        null| 33|
 | Dublin|Honda Accord| 10|
 | Dublin|   Honda CRV|  3|
 | Dublin| Honda Civic| 20|
 | Fremont|        null| 32|
 | Fremont|Honda Accord| 15|
 | Fremont|   Honda CRV|  7|
 | Fremont| Honda Civic| 10|
 |San Jose|        null| 13|
 |San Jose|Honda Accord|  8|
 |San Jose| Honda Civic|  5|
 +--------+------------+---+

再看 Union All 版的执行结果:

 spark-sql> (SELECT city, car_model, sum(quantity) AS sum FROM dealer GROUP BY city, car_model) UNION ALL 
          > (SELECT city, NULL as car_model, sum(quantity) AS sum FROM dealer GROUP BY city) UNION ALL 
          > (SELECT NULL as city, car_model, sum(quantity) AS sum FROM dealer GROUP BY car_model) UNION ALL 
          > (SELECT NULL as city, NULL as car_model, sum(quantity) AS sum FROM dealer) 
          > ORDER BY city, car_model;
 +--------+------------+---+
 |   city|   car_model|sum|
 +--------+------------+---+
 |    null|        null| 78|
 |    null|Honda Accord| 33|
 |    null|   Honda CRV| 10|
 |    null| Honda Civic| 35|
 | Dublin|        null| 33|
 | Dublin|Honda Accord| 10|
 | Dublin|   Honda CRV|  3|
 | Dublin| Honda Civic| 20|
 | Fremont|        null| 32|
 | Fremont|Honda Accord| 15|
 | Fremont|   Honda CRV|  7|
 | Fremont| Honda Civic| 10|
 |San Jose|        null| 13|
 |San Jose|Honda Accord|  8|
 |San Jose| Honda Civic|  5|
 +--------+------------+---+

两版的查询结果完全一样。

Grouping Sets 的执行计划

从执行结果上看,Grouping Sets 版本和 Union All 版本的 SQL 是等价的,但 Grouping Sets 版本更加简洁。

那么, Grouping Sets  仅仅只是  Union All  的一个缩写,或者语法糖吗 ?

为了进一步探究  Grouping Sets  的底层实现是否和  Union All  是一致的,我们可以来看下两者的执行计划。

首先,我们通过  explain extended  来查看 Union All 版本的  Optimized Logical Plan :

 spark-sql> explain extended (SELECT city, car_model, sum(quantity) AS sum FROM dealer GROUP BY city, car_model) UNION ALL(SELECT city, NULL as car_model, sum(quantity) AS sum FROM dealer GROUP BY city) UNION ALL (SELECT NULL as cit
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值