1、遇到一个hive的问题,如下hive sql:


select t1.a,t1.b from table t1 join table2 t2  on ( t1.a=t2.a and t1.datecol=20110802)


该语句中B表有30亿行记录,t1表只有100行记录,而且t2表中数据倾斜特别严重,有一个key上有15亿行记录,在运行过程中特别的慢,而且在reduece的过程中遇有内存不够而报错。

为了解决用户的这个问题,考虑使用mapjoin,mapjoin的原理:

MAPJION会把小表全部读入内存中,在map阶段直接拿另外一个表的数据和内存中表数据做匹配,而普通的equality join则是类似于mapreduce模型中的file join,需要先分组,然后再reduce端进行连接,使用的时候需要结合着场景;由于mapjoin是在map是进行了join操作,省去了reduce的运行,效率也会高很多

这样就不会由于数据倾斜导致某个reduce上落数据太多而失败。于是原来的sql可以通过使用hint的方式指定join时使用mapjoin。

select /*+ mapjoin(t1)*/ t1.a,t1.b from table t1 join table2 t2  on ( t1.a=t2.a and f.ftime=20110802)


再运行发现执行的效率比以前的写法高了好多。



2、mapjoin还有一个很大的好处是能够进行不等连接的join操作,如果将不等条件写在where中,那么mapreduce过程中会进行笛卡尔积,运行效率特别低,这是由于equality join (不等值join操作有 >、<、like等如:a.x < b.y 或者 a.x like b.y) 需要在reduce端进行不等值判断,map端只能过滤掉where中等值连接时候的条件,如果使用mapjoin操作,在map的过程中就完成了不等值的join操作,效率会高很多。


select A.a ,A.b from A join B where A.a>B.a

3、

Mapjoin 不能使用与 outer join


select  /*+ mapjoin(t1)*/ t2.juid from t_pvjoinvv t1   
left outer join
(select distinct juid from t_vvformat where start_date=20130306 and flag=1 and sourceid<3 ) t2
on t1.juid=t2.juid
where t1.start_date=20130306
and t1.pv_1stflag=1
and t2.juid is null ;
" ;

抛出异常:


OK  
Time taken: 1.957 seconds
FAILED: Error in semantic analysis: MAPJOIN cannot be performed with OUTER JOIN


简单总结一下,mapjoin的使用场景:


1. 关联操作中有一张表非常小


2.不等值的链接操作