【Hive】GROUP BY 执行原理-大数据开发高频面试题

   Hive 的执行原理是高频面试题。因为后面的调优或者数据倾斜的处理都是在对其执行原理清楚的基础上进行的。今天以 GROUP BY 为例讲解一下。

1.直观的角度

下表名叫 table1:

idnamenumber
1aaa2
2aaa3
3bbb4
4bbb5
5ccc6
6ddd7
7eee7
8bbb5
9ccc6

如果执行下面的语句:

SELECT name
FROM table1
GROUP BY name;

容易得到结果:

name
aaa
bbb
ccc
ddd
eee

那么到底怎么执行的呢?我们先拆解一下这个过程。SQL 的执行顺序如下:

  1. FROM JOIN
  2. WHERE
  3. GROUP BY
  4. HAVING
  5. SELECT(窗口函数在这里执行)
  6. ORDER BY
  7. LIMIT

于是可以得到:

第一步,先执行 FROM table1,得到的还是原来的表:

idnamenumber
1aaa2
2aaa3
3bbb4
4bbb5
5ccc6
6ddd7
7eee7
8bbb5
9ccc6

第二步,再执行 FROM table1 GROUP BY name 得到下面虚拟的表:

idnamenumber
1
2
aaa2
3
3
4
8
bbb4
5
5
5
9
ccc6
6
6ddd7
7eee7

第三步,执行 SELECT name FROM table1 GROUP BY name ,即可得到答案。

name
aaa
bbb
ccc
ddd
eee

注意:可以看到 id 和 number 里面有多行,这也就是使用了 GROUP BY 后选择其他字段必须使用聚合函数 (如 SUM、MAX 等)的原因。例如,执行下面的 SQL :

SELECT name,SUM(number) AS total
FROM test
ORDER BY name;

可以得到如下结果:

nametotal
aaa5
bbb14
ccc12
ddd7
eee7

如果是 GROUP BY 多字段,道理也一样,例如:

SELECT name,number
FROM table1
GROUP BY name,number;

此时就把 name 和 number 看成整体分组就好了:

idnamenumber
1aaa2
2aaa3
3bbb4
4
8
bbb5
5
9
ccc6
6ddd7
7eee7

最后再得到结果:

namenumber
aaa2
aaa3
bbb4
bbb5
ccc6
ddd7
eee7
2.从 MapReduce 的角度看
  • map 阶段,将 group by 后的字段组合作为 key,如果 group by 单字段那么 key 就一个。
  • 将 group by 之后要进行的聚合操作字段作为值,如要进行 count,则 value 是 1;如要 sum 另一个字段,则 value 就是该字段。
  • shuffle 阶段,按照 key 的不同分发到不同的 reducer。注意此时可能因为 key 分布不均匀而出现数据倾斜的问题。
  • reduce 阶段,将相同 key 的值累加或作其他需要的聚合操作,得到结果。

例如执行下面的语句:

select rank,isonline,count(*)
from city
group by rank, isonline;

在这里插入图片描述

3.GROUP BY 的特性
  • 使用了 reduce 操作,受限于 reduce 数量,通过参数 mapred.reduce.tasks 设置 reduce 个数。
  • 输出文件个数与 reduce 数量相同,文件大小与 reduce 处理的数量有关。
4.GROUP BY 的问题
  • 网络负载过重。
  • 出现数据倾斜(我们可以通过 hive.groupby.skewindata 参数来优化数据倾斜的问题)。
5.GROUP BY 出现数据倾斜的调优方法
  • set hive.map.aggr=true,即开启 map 端的 combiner,减少传到 reducer 的数据量,同时需设置参数 hive.groupby.mapaggr.checkinterval 规定在 map 端进行聚合操作的条目数目。
  • 设置 mapred.reduce.tasks 为较大数量,降低每个 reducer 处理的数据量。
  • set hive.groupby.skewindata=true,该参数可自动进行负载均衡。生成的查询计划会有两个 MR Job。第一个 MR Job 中,Map 的输出结果集合会随机分布到 Reduce 中,每个 Reduce 做部分聚合操作,并输出结果,这样处理的结果是相同的 Group By Key 有可能被分发到不同的 Reduce 中,从而达到负载均衡的目的;第二个 MR Job 再根据预处理的数据结果按照 Group By Key 分布到 Reduce 中(这个过程可以保证相同的 Group By Key 被分布到同一个 Reduce 中),最后完成最终的聚合操作。
6.GROUP BY 和 DISTINCT 去重的区别
  • GROUP BY 是按照 key 进行 hash 分散到多个 Reduce 中处理,速度快;
  • DISTINCT 是把要处理字段全部放到一个 Reduce中 处理,速度慢;
  • 结论:尽量用 GROUP BY 替代 DISTINCT。不过如果 key 类别太多会造成分桶过多。例如 GROUP BY user_id 和 DISTINCT user_id,user_id 可能很多,分桶太多。

欢迎关注。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值