并不是所有的聚合操作都需要在 Reduce 端完成,很多聚合操作都可以先在 Map 端进行 部分聚合,最后在 Reduce 端得出最终结果。 1 )开启 Map 端聚合参数设置 (1)是否在 Map 端进行聚合,默认为 True set hive.map.aggr = true (2)在 Map 端进行聚合操作的条目数目 set hive.groupby.mapaggr.checkinterval = 100000 (3)有数据倾斜的时候进行负载均衡(默认是 false ) set hive.groupby.skewindata = true 当选项设定为 true ,生成的查询计划会有两个 MR Job 。 第一个 MR Job 中, Map 的输出 结果会随机分布到 Reduce 中,每个 Reduce 做部分聚合操作,并输出结果,这样处理的结果 是相同的 Group By Key 有可能被分发到不同的 Reduce 中,从而达到负载均衡的目的;第二 个 MR Job 再根据预处理的数据结果按照 Group By Key 分布到 Reduce 中(这个过程可以保证 相同的 Group By Key 被分布到同一个 Reduce 中),最后完成最终的聚合操作。
4.4 Count(Distinct) 去重统计
数据量小的时候无所谓,数据量大的情况下,由于 COUNT DISTINCT 操作需要用一个 Reduce Task 来完成,这一个 Reduce 需要处理的数据量太大,就会导致整个 Job 很难完成, 一般 COUNT DISTINCT 使用先 GROUP BY 再 COUNT 的方式替换 , 但是需要注意 group by 造成 的数据倾斜问题 . 1 ) 案例实操 (1)创建一张大表(2)加载数据 (3)设置 5 个 reduce 个数 set mapreduce.job.reduces = 5; (4)执行去重 id 查询
(5)采用 GROUP by 去重 id
虽然会多用一个 Job 来完成,但在数据量大的情况下,这个绝对是值得的
4.5 笛卡尔积
尽量避免笛卡尔积, join 的时候不加 on 条件,或者无效的 on 条件, Hive 只能使用 1 个 reducer 来完成笛卡尔积4.6 行列过滤
列处理:在 SELECT 中,只拿需要的列,如果有分区,尽量使用分区过滤,少用 SELECT * 。 行处理:在分区剪裁中,当使用外关联时,如果将副表的过滤条件写在 Where 后面, 那么就会先全表关联,之后再过滤,比如:案例实操:
1 )测试先关联两张表,再用 where 条件过滤2)通过子查询后,再关联表



