hive 的order by ,sort by,distribute by,cluster by

2023-03-06 17:01:43 浏览数 (2)

order by

order by会对输入做全局排序,因此只有一个Reducer(多个Reducer无法保证全局有序),然而只有一个Reducer,会导致当输入规模较大时,消耗较长的计算时间,在生产环境中遇到数据量较大的情况,一般无法成功。

sort by

sort by不是全局排序,其在数据进入reducer前完成排序,因此,如果用sort by进行排序,并且设置mapreduce.job.reduces 多于1个,则sort by只会保证每个reducer的输出有序,但不保证全局有序。

sort by的数据只能保证在同一个reduce中的数据可以按指定字段排序。使用sort by你可以指定执行的reduce个数(通过set mapreduce.job.reduces=n来指定),对输出的数据再执行归并排序,即可得到全部结果。

distribute by

distribute by是控制在map端如何拆分数据给reduce端的。hive会根据distribute by后面列,对应reduce的个数进行分发,默认是采用hash算法。sort by为每个reduce产生一个排序文件。

在有些情况下,你需要控制某个特定行应该到哪个reducer,这通常是为了进行后续的聚集操作。distribute by刚好可以做这件事。因此,distribute by经常和sort by配合使用。

注意

distribute by 的分区规则是根据分区字段的 hash 码与 reduce 的个数进行模除后, 余数相同的分到一个区,也就意味着同一个分区中的分区字段不一定相同。

Hive 要求 distribute by 语句要写在 sort by 语句之前,因为,sort by 是对分区中排序

cluster by

当 distribute by 和 sorts by 字段相同时,可以使用 cluster by 方式

cluster by 除了具有 distribute by 的功能外还兼具 sort by 的功能。但是排序只能是升序排序,不能指定排序规则为 ASC 或者 DESC。

在分区和排序字段相同的前提下他等价于 distribute by 和sort by 的一个简写方式。

演练

数据和建表

tb_loc(地域表)

代码语言:javascript复制
2001    NewYork
2002    Boston
2003    Dallas
2004    Chicago
create table tb_loc(
loc int,
locname string
)
row format delimited fields terminated by 't';

tb_dept(部门表)

代码语言:javascript复制
10  ACCOUNTING  2001
20  RESEARCH    2002
30  SALES   2003
40  OPERATIONS  2004
create table tb_dept(
deptno int,
dname string,
loc int
)
row format delimited fields terminated by 't';

tb_emp(员工表)

代码语言:javascript复制
7369    SMITH   CLERK   7902    1980-12-17  800.00  NULL    20
7499    ALLEN   SALESMAN    7698    1981-02-20  1600.00 300.00  30
7521    WARD    SALESMAN    7698    1981-02-22  1250.00 500.00  30
7566    JONES   MANAGER 7839    1981-04-02  2975.00 NULL    20
7654    MARTIN  SALESMAN    7698    1981-09-28  1250.00 1400.00 30
7698    BLAKE   MANAGER 7839    1981-05-01  2850.00 NULL    30
7782    CLARK   MANAGER 7839    1981-06-09  2450.00 NULL    10
7788    SCOTT   ANALYST 7566    1987-04-19  3000.00 NULL    20
7839    KING    PRESIDENT   NULL    1981-11-17  5000.00 NULL    10
7844    TURNER  SALESMAN    7698    1981-09-08  1500.00 0.00    30
7876    ADAMS   CLERK   7788    1987-05-23  1100.00 NULL    20
7900    JAMES   CLERK   7698    1981-12-03  950.00  NULL    30
7902    FORD    ANALYST 7566    1981-12-03  3000.00 NULL    20
7934    MILLER  CLERK   7782    1982-01-23  1300.00 NULL    10
7934    TOM CLERK   7782    1982-01-23  1200.00 NULL    50
7934    JACK    CLERK   7782    1982-01-23  1100.00 NULL    60
代码语言:javascript复制
create table tb_emp(
empno int,
ename string,
job string,
mgr int,
hiredate string,
sal float,
comm float,
deptno int
)
row format delimited fields terminated by 't';

导入数据

代码语言:javascript复制
load data local inpath '/hivedata/dept.txt' into table tb_dept;
load data local inpath '/hivedata/emp.txt' into table tb_emp;
load data local inpath '/hivedata/loc.txt' into table tb_loc;

Order By

代码语言:javascript复制
-- 全局排序,只有一个reduce
hive (default)> select * from tb_epm order by sal;
​
-- 按照别名排序
hive (default)> select ename,sal*2 as 2sal from tb_emp order by 2sal;
​
-- 多个列排序
hive (default)> select ename, deptno, sal from tb_emp order by deptno, sal;

每个 Reduce 内部排序(Sort By)

代码语言:javascript复制
-- 设置 reduce 个数
hive (default)> set mapreduce.job.reduces=3;
​
-- 查看设置 reduce 个数
hive (default)> set mapreduce.job.reduces;
​
-- 每个reduce内部按照deptno 降序排列
hive (default)> select * from tb_emp sort by deptno desc;
​
-- 将查询结果导入到文件中
hive (default)> insert overwrite local directory 
'/hivedata/sortby-result'
select * from tb_emp sort by deptno desc;

Distribute By

代码语言:javascript复制
--先按照部门编号分区,再按照员工编号降序排序
hive (default)> set mapreduce.job.reduces=3; 
hive (default)> insert overwrite local directory
'/hivedata/distribute-result' 
select * from tb_emp distribute by deptno sort by empno desc;

distribute by 的分区规则是根据分区字段的 hash 码与 reduce 的个数进行模除后, 余数相同的分到一个区。

注意:DISTRIBUTE BY 语句要写在 SORT BY 语句之前

Cluster By

当 distribute by 和 sorts by 字段相同时,并且排序为升序时,可以使用 cluster by 方式。

cluster by = distribute by sorts by

只能是升序排序,不能指定排序规则为 ASC 或者 DESC。

代码语言:javascript复制
-- 下面这两个的结果是一样的
-- 满足条件,即cluster by 和 sort by 的字段相同,并且是升序排列
hive (default)> select * from tb_emp cluster by deptno;
hive (default)> select * from tb_emp distribute by deptno sort by deptno;

0 人点赞