目录

  • 1.前言
  • 2.order by
  • 3.sort by
  • 4.distribute by
  • 5.Cluster By
  • 6.实际需求


1.前言

hive中的四个by分别为order by,sort by,distribute by,cluster by;
下面具体讲解:

2.order by

全局排序,只有一个reduce;
缺点:当数据量非常大时,耗时太长,效率低下,适用于数据量较小的场景;
优点:数据全局排序;

select * from emp order by sal desc;

备注:当你使用order by时,默认只走一个reduce,和你设多少个reduce个数无关;

3.sort by

对每一个reducer内部的数据进行排序,全局结果集来说不是排序的,即只能保证每一个reduce输出的文件中的数据是按照规定的字段进行排序的;适用于数据量较大,但对排序要求不严格的场合,可以大幅度提升执行效率;

set mapreduce.job.reduces=3
set mapreduce.job.reduces;
select * from emp sort by deptno desc;

备注:需要你预先设置reduce个数,结果各个reduce文件内部有序,全局无序;

4.distribute by

控制特定的key到指定的reducer,方便后续的聚集操作,类似MR中partition(自定义分区),一般结合sort by使用;
这边需要设置reduces的数量为分区的数量,否则不会启动相应的reducer去进行任务的执行,这最终会导致不能完全分区;

hive (default)> set mapreduce.job.reduces=3;
hive (default)> select * from emp distribute by deptno sort by empno desc;

注意:
1. distribute by的分区规则是根据分区字段的hash码与reduce的个数进行模除后,余数相同的分到一个区。
2. Hive要求distribute by语句要写在sort by语句之前;

5.Cluster By

当distribute by和sorts by字段相同时,可以使用cluster by方式。
cluster by除了具有distribute by的功能外还兼具sort by的功能。但是排序只能是升序排序,不能指定排序规则为ASC或者DESC。
1)以下两种写法等价

hive (default)> select * from emp cluster by deptno;
hive (default)> select * from emp distribute by deptno sort by deptno;

补充:分桶表
对于一张表或者分区,Hive 可以进一步组织成桶,也就是更为细粒度的数据范围划分;

create table stu_buck(id int, name string)
clustered by(id) 
into 4 buckets
row format delimited fields terminated by '\t';

6.实际需求

现在有一亿条数据,比如people_info,取出财富最高的前100位;
分析:显然需要排序,首先想到用order by ,可是显然不行,order by 效率太低,耗时太长;现在思考能不能先走多个reduce,区内有序,最后再全局排序;
具体实现:

select 
*
from 
(select 
id,
name,
money
from  peopel _info 
distribute by loc sort by money limit 100) tmp
order by money limit 100;

备注:这里loc字段是peopel _info 里面自身就有的,如果没有你需要自己添加类似字段,比如level(按money 大小分level,可以用case when 函数,最终可以distribute by level sort by money ),这里方便记忆可以简单这么记,先distribute by sort by ,最后再order by ;