where查询
select * from user where name = ‘liguozhong’;
where 操作是在多个map端进行的。
group by
select name age count(1),avg(age),sum(money),count(distinct age)
form user where sex = 'b'
group by name,age having(avg(age) > 10);
group by在reduce端执行,根据name+age的组合key。发到多个reduce端执行聚合操作,一个组合key对应一个reduce,set mapred.reduce.tasks=10。通过网络传输到对应reduce,如果 name+age分散在各个不同的文件上,传输压力就大。当name+age一个有5个组合数。如果有4个key的数据量小,1个key的数据量很大,拖累了整个job的速度。造成数据倾斜。需要设置 set hive.groupby.skewindata=true;多开一个辅助job来处理数据倾斜。select name,必须是groupby组合键里的列。
order by
select name ,age form user where name = 'liguozhong' order by age desc,sex asc;
order by 是多个map过滤完where的数据,传到一个reduce中排序。单机reduce压力大。慎用。真的要做排序最好是将多个map端过滤完where操作后的数据。导入mysql等关系型数据库中,去做排序。也就是说,这个功能基本没用。
join(join 在reduce端完成)
1 join
selct u.name,s.grade (select * from user) u join (select * from student) s on u.id = s.id
join是内连接,当 id = 3 ,3 同时在user中,和student中的都有记录。才会查出来。
2 left outer join
selct u.name,s.grade (select * from user) u left outer join (select * from student) s on u.id = s.id
left outer join 做连接,当id = 3,只要3在user 表中的数据都会查出来。student 中因为没有3,对应的值回事NULL。
3 right outer join
selct u.name,s.grade (select * from user) u right outer join (select * from student) s on u.id = s.id
right outer join 右连接,当id = 3,只要3在student 表中的数据都会查出来。user 中因为没有3,对应的值回事NULL。
4 left semi join (exist)
selct u.name,s.grade (select * from user) u left semi join (select * from student) s on u.id = s.id and u.name=s.name(on 关联只能是 = 号)
left semi join 连接,当id = 3,只要3在user 表中的数据都会查出来。student 中因为没有3,对应的值回事NULL。在student找到一个值后,就停止了。
5 mapjoin(join 在reduce端)
mapjoin 在map端完成join操作。 join后的 where在reduce端执行。讲一张小表读入map的内存中,当有一张小表和不等值的连接。可以使用mapjoin
set hive.enforce.bucking=true
create table user(
name string,
sex int,
age int
)
clustered by (sex) sorted by(age) into 10 buckets
row format delimited fields terminated by '\t' as textfile;
select * from user tablesample(bucket 1 out of 2 on sex)
set hive.optimize.bucketmapjoin = true;
set hive.optimize.bucketmapjoin.sourtedmerge=true;
set hive.forma=org.apache.hadoop.hive.ql.io.BucketizedHiveInputForMat;
需要样本的场景。按分桶join。
distribute by ( sorted by)
select * from user distribute by name; //按 name 把不同的name的hash数据打散到对应的reduce端。供sorted by使用来实现hive的排序。
select * from user distribute by name sorted by name asc,age desc; //sorted by 在各个reduce端做排序,在单个sorted by 中有序。
set mapred.reduce.tasks = 10;
insert overwrite table user select name,age from student distribute by grade;
cluster by
有空再说。
union all
有空再说。