第一:hive 的类 SQL 语句本身进行调优
1:尽量尽早地过滤数据,减少每个阶段的数据量,对于分区表要加分区,同时只选择需要使用到的字段
select ... from A
join B
on A.key = B.key
where A.userid>10
and B.userid<10
and A.dt='20120417'
and B.dt='20120417';
应该改写为:
select .... from (select .... from A
where dt='201200417'
and userid>10
) a
join ( select .... from B
where dt='201200417'
and userid < 10
) b
on a.key = b.key;
2:尽量原子化操作,尽量避免一个 SQL 包含复杂逻辑
建 view 表,中间表
4:慎重使用 mapjoin,一般行数小于 2000 行,大小小于 1M(扩容后可以适当放大)的表才能使用,小表要
注意放在 join 的左边(目前 TCL 里面很多都小表放在 join 的右边)。
否则会引起磁盘和内存的大量消耗
5. 写 SQL 要先了解数据本身的特点,如果有 join ,group 操作的话,要注意是否会有数据倾斜
如果出现数据倾斜,应当做如下处理:
set hive.exec.reducers.max=200;
set mapred.reduce.tasks= 200;---增大 Reduce 个数
set hive.groupby.mapaggr.checkinterval=100000 ;--这个是 group 的键对应的记录条数超过这个
值则会进行分拆,值根据具体数据量设置
set hive.groupby.skewindata=true; --如果是 group by 过程出现倾斜 应该设置为 true
set hive.skewjoin.key=100000; --这个是 join 的键对应的记录条数超过这个值则会进行分拆,值根据
具体数据量设置
set hive.optimize.skewjoin=true;--如果是 join过程出现倾斜 应该设置为 true
3.1 空值产生的数据倾斜