hive join 优化

1. 表的连接顺序     

   select a.xx,b.xx from  table  a  join table  b  和   select a.xx,b.xx from  table  b join table  a  效果是不一样的 。左边(前面)的表 是被缓存(buffer)在memory中,而右边(后面)的表是被streamed  (官方说明:In every map/reduce stage of the join, the last table in the sequence is streamed through the reducers where as the others are buffered.)。因此小表被buffer可以减少reduce阶段  memory的开销.即 小表放到左边

   当然我们也可以指定哪个表被streamed . 例如:

    select  /*+ STREAMTABLE(a) */  a.xx,b.xx from table a join table b on  a.xx=b.xx .这样左边的表a会被streamed

 

2.  join  on的条件发生在 where 之前

     sql1: SELECT a.val, b.val FROM a LEFT OUTER JOIN b ON (a.key=b.key) WHERE a.ds='2009-07-07' AND b.ds='2009-07-07'

    对于 sql1  ,会先过滤on 中的条件(a.key = b.key) ,然后再过滤where中的条件。试想 如果 a.key=b.key 不匹配的情况下 得到 b.val   b.ds 等所有的关于b的将会是null,再执行where中的条件 b.ds='2009-07-07'  肯定是要被过滤的。居然如此我们为什么不把where中的条件访问on 条件中呢?这样可以提前过滤数据, 修改后如sql2:

   sql2: SELECT a.val, b.val FROM a LEFT OUTER JOIN b  ON (a.key=b.key AND b.ds='2009-07-07' AND a.ds='2009-07-07')

 

3. map side  join

    map-side join 是一种特殊类型的join。如果join 有一个较小的表 ,这个小表可以加载到in-memory构成hash map,直接在map/reduce 过程中的map阶段完成join(官网:MAPJOINs are processed by loading the smaller table into an in-memory hash map and matching keys with the larger table as they are streamed through.)

     明确指定 mapjoin  : select  /*+ MAPJOIN(b) */  a.xx ,b.xx  from a join b on a.xx = b.xx

    或者shell 设置 hive> set hive.auto.convert.join=true;
                                          hive> set hive.auto.convert.join.noconditionaltask=true;

                                          hive > set hive.auto.convert.join.noconditionaltask.size = 10000000; //该属性可以控制多大的表可以自动触发放到内层中,默认大小为(10M)

   备注:1. 如果join 是 full  join类型  就不能使用 map-side了,因为左右两个表都需要被streamed

 

4.sort-merge-bucket join 转化为cmb map join

       如果参与join的表是按照join 列分的桶,并且一个表分桶的个数是一个表分桶个数的整数倍,那么就可以根据桶进行join. e.g :  select /* + MAPJOIN(b) */ a.key,a.value from a join b on a.key=b.key . 对于A中每个mapper,并不需要获取所有B中的数据,仅仅对应的桶中的数据是可以fetch 配置的(需要设置参数 set hive.optimize.bucketmapjoin = true)

       进一步来说,如果参与join的表除了按照join列分的桶,并且还是排序的  ,  一个 sort-merge join 可以是被执行的,下面的参数需要是被设置的(set hive.input.format=org.apache.hadoop.hive.ql.io.BucketizedHiveInputFormat;
set hive.optimize.bucketmapjoin = true;
set hive.optimize.bucketmapjoin.sortedmerge = true;)

 

5.  join 是从左向右关联的

     sql : select a.xx , b.xx , c.xx  from  a  join b on (a.xx= b.xx)  left join  c on (a.xx = c.xx)

     执行过程是先 a 和 b 进行join  ,生成的结果 在和 c进行 left join 。如果 表 a 、b、c中关联(on)条件 仅仅用到一个字段,将生成一个map-reduce 任务

    例如: 

    SELECT a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key1)  仅仅一个map-reduce任务 

    SELECT a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key2)   生成2个map-reduce 任务 

 

 

6.问题:  map side 将小表 加载到 in-memory构成hash map 和  1中指出的将左边的表缓存(buffer)到in-memory 有什么不同呢? 或者说 hash map 到底是什么结构 buffer 存储的到底是什么呢?

 

   参考链接: https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Joins

                      https://cwiki.apache.org/confluence/display/Hive/LanguageManual+JoinOptimization

你可能感兴趣的:(hive)