hive优化原则

来源:互联网 发布:淘宝手机端描述尺寸 编辑:程序博客网 时间:2024/05/17 08:32

转载:http://blog.sina.com.cn/s/blog_9f48885501017cq8.html

使用过hive一段时间,发现楼主讲的非常正确。

基本原则:

1:尽量尽早地过滤数据,减少每个阶段的数据量,对于分区表要加分区,同时只选择需要使用到的字段

select... from A

joinB

on A.key= B.key

whereA.userid>10

     andB.userid<10

       and A.dt='20120417'

       and B.dt='20120417';

应该改写为:

select.... from (select .... from A

                  wheredt='201200417'

                                  and userid>10

                             ) a

join (select .... from B

       wheredt='201200417'

                    and userid <10   

     )b

on a.key= b.key;

2:尽量原子化操作,尽量避免一个SQL包含复杂逻辑

可以使用中间表来完成复杂的逻辑

droptable if exists tmp_table_1;

createtable if not exists tmp_table_1 as

select......;

 

droptable if exists tmp_table_2;

createtable if not exists tmp_table_2 as

select......;

 

droptable if exists result_table;

createtable if not exists result_table as

select......;

 

droptable if exists tmp_table_1;

droptable if exists tmp_table_2;

 

 

3:单个SQL所起的JOB个数尽量控制在5个以下

 

4:慎重使用mapjoin,一般行数小于2000行,大小小于1M(扩容后可以适当放大)的表才能使用,小表要注意放在join的左边(目前TCL里面很多都小表放在join的右边)。

否则会引起磁盘和内存的大量消耗

 

5:写SQL要先了解数据本身的特点,如果有join ,group操作的话,要注意是否会有数据倾斜

如果出现数据倾斜,应当做如下处理:

sethive.exec.reducers.max=200;

setmapred.reduce.tasks= 200;---增大Reduce个数

sethive.groupby.mapaggr.checkinterval=100000;--这个是group的键对应的记录条数超过这个值则会进行分拆,值根据具体数据量设置

sethive.groupby.skewindata=true; --如果是group by过程出现倾斜 应该设置为true

sethive.skewjoin.key=100000;--这个是join的键对应的记录条数超过这个值则会进行分拆,值根据具体数据量设置

sethive.optimize.skewjoin=true;--如果是join 过程出现倾斜应该设置为true

 

6:如果union all的部分个数大于2,或者每个union部分数据量大,应该拆成多个insertinto 语句,实际测试过程中,执行时间能提升50%

insertoverwite table tablename partition (dt= ....)

select..... from (

                   select... from A

                   unionall

                   select... from B

                  union all

                   select... from C

                              ) R

where...;

 

可以改写为:

insertinto table tablename partition (dt= ....)

select.... from A

WHERE...;

 

insertinto table tablename partition (dt= ....)

select.... from B

WHERE...;

 

insertinto table tablename partition (dt= ....)

select.... from C

WHERE...; 


1 0
原创粉丝点击