hive sql 优化 – 2.0

hive 优化

1、需要计算的指标真的需要从数据仓库的公共明细自行汇总吗?
2、真的需要扫描那么多的分区么?
3、尽量不要使用 select * from table这样的方式
4、输入文件不要是大量的小文件

 

group by引起的倾斜优化:

R:group by引起的倾斜主要是输入数据行按照group by列分布不均匀引起的。
S:优化方案:
set hive.map.aggr = true
set hive.groupby.skewindata=true

 

count distinct优化
eg: select count(distinct user) from some_table;
R:由于必须去重,因此hive会将Map阶段的输出全部分不到一个Reduce Task上,因此很容引起性能问题
S:
select count(*)
from
(
select user
from some_table
group by user
) tmp

利用gourp by 去重,再统计group by 的行数目

 

大表join小表优化
join相关的优化主要分为mapjoin 可以解决的优化(即大表join小表)和mapjoin无法解决的优化(即大表join大表)

eg:以销售明细事实表与供应商维度关联。
R:二八法则会导致订单集中在部分供应商上,因此在处理数据时容易加剧数据倾斜
S:直接使用mapjoin

 

大表join大表优化

1、转换为mapjoin: 通过限制行和列的方式看看能否将大表转换为小表,从而进行mapjoin。

2、join时用case when语句
前提:倾斜的值时明确的而且数量很少,比如null值引起的倾斜。其核心是将这些引起倾斜的值随机分发到Reduce,其主要核心逻辑在于join时对这些特殊值concat随机数,从而达到分发的目的。

3、倍数B表,再取模join
1)通用方案:
建立一个numbers表,其值只有一列int行,比如从1到10(具体值可根据倾斜成都确定)。然后让其中一个表join number,放大该表10倍。因为group by一个字段会发生倾斜,那么在人公司增加一列进行group by, 再分发数据的时候就会变成之前的1/10

2)专用方案:
通用方案把B 表的每条数据都放大了相同的倍数,实际上这是不需要的,只需要把大卖家放大倍数即可。

步骤:
a)需要知道大卖家的名单,先建立一个临时表动态存放每日最新的大卖家,同时此表的大卖家要膨胀到预先设定的倍数(比如1000倍)
b)在A表和B表分别新建一个join列,其逻辑为:如果是大卖家,那么concat一个随机分配正整数(0到预定的倍数之间,本列是0-1000);如果不是,保持不变。

4、动态一分为二
终极解决方案就是动态一份为二,即对倾斜的键值和不倾斜的键值分开处理,不倾斜的正常join即可,倾斜的把他们找出来然后做mapjoin,最后做union all其他结果即可。

相关文章