Xc's Blog

HQL优化

1996/10/01 Share

根本思想

  • 尽早过滤数据,减少每个阶段数量
  • 减少job数量
  • 解决数据倾斜

过滤数据

列裁剪

只查询必要的列,不被查询的列可以不被访问,提升性能

分区裁剪

减少不必要的分区

利用Hive的优化机制减少job数量

out join inner join,如果是join的key相同,不论表的数量,都会合并为一个mapReduce任务

job的输入输出优化

善用muti-insert, union all,不同表的union all相当于multiple inputs,同一个表的union all,相当map一次输出多条

1
2
3
4
5
6
7
8
9
10
11
insert overwrite table tmp1
select … from a where 条件1;
insert overwrite table tmp2
select… from a where 条件2;
扫描两次a表
from a
insert overwrite table tmp1
select… where 条件1
insert overwrite table tmp2
select… where 条件2;
只扫描一次a表

Join优化

避免笛卡尔积

1
2
3
4
5
6
7
8
9
select …
from woa_all_device_info_his A
left outer join (
select * from woa_all_info_his B
where (B.mobile <> ‘unknown’ or B.imsi <> ‘unknown’)
and B.imei <> ‘unknown’
and B.pt = ‘$data_desc’
) C
on A.app_id = C.app_id and A.imei = C.imei

数据过滤

在join前过滤掉不需要的数据

小表放前大表放后原则

在编写带有join操作的代码语句时,应该将条目少的表/子查询放在join操作符的左边

因为在Reduce阶段,位于join操作符左边的表的内容会被加载进内存,载入条目较少的表可以有效减少OOM。所以对于同一个key来说,对应的value值小的放前,大的放后。

map join 来避免数据倾斜

数据倾斜一般是由于代码中的join或group by或distinct的key分布不均导致的

Join算法一般有两种

- (map side join)    replication join:把其中一个表复制到所有节点,这样另一个表在每个节点上面的分片就可以跟这个完整的表join了
- (reduce side join) repartition join:把两份数据按照join key进行hash重分布,让每个节点处理hash值相同的join key数据,也就是做局部的join

合理使用left semi join

left semi 是比 In exist 效率高的一种方式

合理使用动态分区

CATALOG
  1. 1. 根本思想
  2. 2. 过滤数据
    1. 2.1. 列裁剪
    2. 2.2. 分区裁剪
    3. 2.3. 利用Hive的优化机制减少job数量
    4. 2.4. job的输入输出优化
  3. 3. Join优化
    1. 3.1. 避免笛卡尔积
    2. 3.2. 数据过滤
    3. 3.3. 小表放前大表放后原则
    4. 3.4. map join 来避免数据倾斜
      1. 3.4.1. Join算法一般有两种
    5. 3.5. 合理使用left semi join
    6. 3.6. 合理使用动态分区