hive的join相关分析:
hive常用的join有两大类:
- common join/reduce join/shuffle join 一般的join
- mapjoin 优化器优化后的join
hive默认使用的join:
- 当 hive.auto.convert.join = true时,优化器默认将common join转化成mapjoin
- 当 hive.auto.convert.join = false时,默认使用 common join
测试SQL:
select e.empno, e.ename, e.deptno, d.dname
from emp e join dept d on e.deptno=d.deptno;
-- shuffle:将相同的deptno分到一个reduce上去
-- emp表所需列 :<deptno,(empno,ename)>
-- dept表所需列:<deptno,(dname)>
-- 正常的操作如以上分析,分别扫表取出emp表和dept表对应的列
-- 然后将列deptno相同的数据分配到一个reduce上去,查出数据
该SQL的common join执行计划解读:
set hive.auto.convert.join = false;
explain
select e.empno, e.ename, e.deptno, d.dname
from emp e join dept d on e.deptno=d.deptno;
-- 设置优化器参数为false,使用explain关键字查看执行计划
common join 执行了两步,第一步是map+reduce,第二部是展示数据,
第一步中,map操作分别对两表进行扫描,根据deptno分组,查出需要的列数据,传递给reduce,
然后在reduce操作中进行join操作,最终得出结果数据集。
该SQL的mapjoin执行计划解读:
set hive.auto.convert.join = true;
explain
select e.empno, e.ename, e.deptno, d.dname
from emp e join dept d on e.deptno=d.deptno;
mapjoin比common join多了一步,首先启动了一个本地的Map Reduce作业,读d表,
然后启动了一个非本地的Map Reduce作业,是一个真实的Map操作,读e表,
然后并没有启动真实的Reduce操作,而直接在Map端进行了join操作,最后展示数据。
使用优化器将commmon join 优化成mapjoin,省掉了Reduce操作,效率更高。
两种join的进一步分析:
两表进行common join,需要对两表分别启动一组map作业,将数据根据join的条件进行排序,
经过网络shuffle后传输到同一个reduce作业,然后启动该reduce作业,进行join,然后查出数据。
这中join性能是较差的,因为两表的数据map之后需要经过shuffle进行网络传输。
两表进行mapjoin,首先启动一个本地的MR Local Task,会去读小表(根据表的元数据中的统计信息确定),将小表的数据读入之后生成一个HashTable文件,将该文件存入hadoop的分布式缓存中;
然后启动一个Map任务,将另外一个表的数据读入之后和上一步存入到入hadoop的分布式缓存中的HashTable文件进行join操作,查出数据。
这种join是没有shuffle进行网络传输的,是性能比较高的join方法。
来自@若泽大数据