1.hive join的实现方式
1、hive HQL语句 要被翻译成MR程序
2、MR中的Join操作有两种:MapJoin 和 ReduceJoinselect a.*, b.* from a join b on a.id= b.id;
hive的引擎会启动检测两个输入的大小,如果有一方小于默认的25M,那么会自动转化成MapJoin
调优的一个小标准:可以上调这个25M
如果真的是小表是 990M, 然后自动转化成MapJoin的标准是1G:
出现的问题:如果大表的数据过大,那么就有可能造成所有的节点执行MapTask的个数过多
占用内存的数量; 每个MapTask都占用一个990M数据的内存
2.hive 注意点
1、hive只支持等值连接, 不支持 > < != 为什么?
支持不支持,能不能顺利的转换成MR
select a.*, b.* from a join b on a.id > b.id;
2、join操作中只支持 and 不支持 or
select a.*, b.* from a join b on (a.id = b.id and b.age = b.age) √√√√√
select a.*, b.* from a join b on (a.id = b.id or b.age = b.age) XXXXX
如果按照age和id作为联合key,那么最终能够连上的数据一定是 左边的id和age 与 右边的id和age都相等, 只有都相等,才会进入同一个reduce方法
3、Join可以多于两个表
select a.*, b.* ,c.* from a join b on a.id = b.id join c on a.id = c.id;
首先,这个HQL语句能不能顺利的翻译成MR程序?
可以使用几个MR来实现该程序? 1
select a.*, b.*, c.* from a join b on (a.id = b.id and a.age = b.age) join c on a.name = c.name;
该HQL语句能不能被翻译成MR程序?
可以使用几个MR程序来实现该程序? 2
作为连接条件的字段组合有几个,就需要至少翻译成几个MR程序
4、在多表连接中,尽量把大表放置在最后
为什么?
hql语句被翻译成MR程序的时候是按顺序执行,假如a是大表:
a : 500W b: 10000, c: 100
a.id = b.id
a.name = c.name
c join a join b
a*b
(a*b)*c
c*b
(c*b) * a
限制:只适合使用在多字段连接的时候尽量这么做
3.hive Join的分类:
Join分五类:
外链接
左外链接
右外连接
全外链接
内连接
semi join
4.hive join操作
drop table if exists a;
create table a(id int, name string) row format delimited fields terminated by ',';
load data local inpath "/home/hadoop/a.txt" into table a;
select * from a;
drop table if exists b;
create table b(id int, age int) row format delimited fields terminated by ',';
load data local inpath "/home/hadoop/b.txt" into table b;
select * from b;
a.txt
1,huangbo
2,xuzheng
4,liujialing
5,liutao
7,liangchaowei
8,liudehua
b.txt
3,11
4,22
5,33
6,55
9,99
外链接
select a.id, a.name, b.age from a left join b on a.id = b.id;
select a.id, a.name, b.age from a full join b on a.id = b.id;
// 内连接
select a.id, a.name, b.age from a join b on a.id = b.id;
select a.id, a.name, b.age from a inner join b on a.id = b.id;
// semi join在使用的时候,只能查取左表的字段,不能查取右表的字段
select a.id, a.name from a left semi join b on a.id = b.id;
// select a.id, a.name from a where a.id in (select b.id from b)