hive四种排序Order By , Sort By ,Distribute By ,Cluster By

hive四种排序Order By , Sort By ,Distribute By ,Cluster By前文Hive的本质是MapReduce,MapReduce中如何排序的??MapReduce分为几种:1.全排序orderBy:结果只有一个(也就是只有一个分区),所有的数据整体有序.2.部分排序sortBy:结果有多个(相当于有多个分区),每个分区内部有序的.3.二次排序:在排序时,比较的条件有多个,比如说按总流量排序,总流量相等就按上行流量排序.注意:排序是在reduce之前就已经排好序了,排序是shuffle阶段的主要工作.然后让Reduce方便接下来的处理准备数据

前文

Hive的本质是MapReduce,MapReduce中如何排序的??

MapReduce分为几种:
1.全排序order By: 结果只有一个(也就是只有一个分区),所有的数据整体有序.
2.部分排 序sort By: 结果有多个(相当于有多个分区),每个分区内部有序的.
3.二次排序: 在排序时,比较的条件有多个,比如说按总流量排序,总流量相等就按上行流量排序.

注意:
排序是在reduce之前就已经排好序了,排序是shuffle阶段的主要工作.然后让Reduce方便接下来的处理

准备数据

准备 emp.txt到/root/soft 目录下面,

7369	SMITH	CLERK	7902	1980-12-17	800.00		20
7499	ALLEN	SALESMAN	7698	1981-2-20	1600.00	300.00	30
7521	WARD	SALESMAN	7698	1981-2-22	1250.00	500.00	30
7566	JONES	MANAGER	7839	1981-4-2	2975.00		20
7654	MARTIN	SALESMAN	7698	1981-9-28	1250.00	1400.00	30
7698	BLAKE	MANAGER	7839	1981-5-1	2850.00		30
7782	CLARK	MANAGER	7839	1981-6-9	2450.00		10
7788	SCOTT	ANALYST	7566	1987-4-19	3000.00		20
7839	KING	PRESIDENT		1981-11-17	5000.00		10
7844	TURNER	SALESMAN	7698	1981-9-8	1500.00	0.00	30
7876	ADAMS	CLERK	7788	1987-5-23	1100.00		20
7900	JAMES	CLERK	7698	1981-12-3	950.00		30
7902	FORD	ANALYST	7566	1981-12-3	3000.00		20
7934	MILLER	CLERK	7782	1982-1-23	1300.00		10

创建表

注意, 分隔符不要写错了,不然导入数据会导入不进来.

sql:

create external table if not exists emp
(
    empno    int,
    ename    string,
    job      string,
    mgr      int,
    hiredate string,
    sal      double,
    comm     double,
    deptno   int
) row format delimited fields terminated by '\t';

select *
from emp;

导入数据

如果导入数据失败,看看是不是分隔符弄错了,我曾经就出现过这个错误,弄了20分钟找不到问题,最后发现创建表的语句 \t 我给写成了 /t … = =. 结果就出现导入失败的情况.
sql:

load data local inpath '/root/soft/emp.txt'
    into table emp;

查看导入的结果

sql


select *
from emp;

Order By全排序

Order By:全局排序,一个ReducerTask,也就是对所有的数据进行排序.如果多个Reduce的话是无用的.

使用 ORDER BY 子句排序

ASC(ascend): 升序(默认)
DESC(descend): 降序

案例
使用上和MySQL的order by没啥区别


	-- 查询员工信息按工资升序排列
hive (default)> select * from emp order by sal;
 -- 查询员工信息按工资降序排列
hive (default)> select * from emp order by sal desc;

Sort By 每个MapReduce内部排序

使用Sort By 的话, 需要将ReduceTask最少要大于1,不然没效果. 一个ReduceTask就是一个分区,五个ReduceTask就是五个分区.

每个Reducer内部进行排序,对全局结果集来说不是排序。

操作说明
设置Reduce个数
sql:

-- 1.设置reduce个数
set mapreduce.job.reduces=3;
-- 2.查看设置reduce个数
set mapreduce.job.reduces;
--3.根据部门编号降序查看员工信息
select *
from emp sort by empno desc;

这样执行完了你会发现数据都是乱的,没有什么效果…

在这里插入图片描述

需要将数据导出到文件里面才能看到效果
sql

-- 将查询的语句导入到指定文件里面

insert overwrite local directory '/root/soft/sortby-result'
    row format delimited fields terminated by '\t'
select *
from emp sort by sal desc;

此时Linux的/root/soft下会生成一个sortby-result文件夹
为什么是三个???
因为启动了三个ReduceTask 任务

[root@zjj101 soft]# cd sortby-result/
[root@zjj101 sortby-result]# ls
000000_0  000001_0  000002_0
[root@zjj101 sortby-result]# pwd
/root/soft/sortby-result
[root@zjj101 sortby-result]# 

依次查看这三个文件里面的内容

根据sal 降序排序,sal字段是从左往右数第六个字段, 你就能看到每个ReduceTask(分区)内部都是有序排列的了.

shell

[root@zjj101 sortby-result]# ls
000000_0  000001_0  000002_0
[root@zjj101 sortby-result]# cat 000000_0 
7839    KING    PRESIDENT       \N      1981-11-17      5000.0  \N      10
7788    SCOTT   ANALYST 7566    1987-4-19       3000.0  \N      20
7698    BLAKE   MANAGER 7839    1981-5-1        2850.0  \N      30
7782    CLARK   MANAGER 7839    1981-6-9        2450.0  \N      10
7844    TURNER  SALESMAN        7698    1981-9-8        1500.0  0.0     30
7654    MARTIN  SALESMAN        7698    1981-9-28       1250.0  1400.0  30
[root@zjj101 sortby-result]# cat 000001_0 
7566    JONES   MANAGER 7839    1981-4-2        2975.0  \N      20
7499    ALLEN   SALESMAN        7698    1981-2-20       1600.0  300.0   30
7934    MILLER  CLERK   7782    1982-1-23       1300.0  \N      10
7521    WARD    SALESMAN        7698    1981-2-22       1250.0  500.0   30
7876    ADAMS   CLERK   7788    1987-5-23       1100.0  \N      20
7900    JAMES   CLERK   7698    1981-12-3       950.0   \N      30
[root@zjj101 sortby-result]# cat 000002_0
7902    FORD    ANALYST 7566    1981-12-3       3000.0  \N      20
7369    SMITH   CLERK   7902    1980-12-17      800.0   \N      20
[root@zjj101 sortby-result]# 

Distribute By 分区排序

分区和排序都是在shuffle阶段完成,分区是在MapTask阶段的Shuffle完成, 排序是在MapTask完成,在ReduceTask也有完成.
分区是使用partition分区器来进行分区的,当你的ReduceTask的个数大于1的时候,先设置用户自己定义的分区器,如果没有的话,缺省使用hash分区器,hash分区器特点是只用key的hashCode来分区.

你在输入查询语句执行查询的时候,底层是经过了MapReduce程序,会给你输入的字段都封装成key和value,分区只是对key来分区.那么你不知道你哪些数据分散到哪个ReduceTask里面.

如果你只写sort by的话,那么就是随机分区.如果你希望自己定义使用哪个字段来分区,那么你就需要使用Distribute By字段,这个Distribute By是指定你按哪个字段分区的. Distribute By在全排序是没有意义的,因为全排序是只有一个ReduceTask,那么不管你key是什么的话,全都是0号分区,所以说Distribute By只有结合部分排序才有意义的.所以一般情况下Distribute By 是结合sort by 来使用的

注意,Hive要求DISTRIBUTE BY语句要写在SORT BY语句之前。

对于distribute by进行测试,一定要分配多reduce进行处理,否则无法看到distribute by的效果。

案例

先按照部门编号分区,再按照员工编号降序排序。

sql:

set mapreduce.job.reduces=3;
insert overwrite local directory '/root/soft/sortby-result'
    row format delimited fields terminated by '\t'
select *
from emp distribute by deptno
    sort by empno desc;

注意: overwrite 这个是自动删除指定的目录.

执行完了之后会生成三个文件,因为是三个ReduceTask

仔细观察,部门号是最右面的那个,是按照部门号排序的,默认是hash分区器,然后每个ReduceTask内部是按照员工编号排序的,员工编号是最左面的一个字段.

[root@zjj101 soft]# cd sortby-result/
[root@zjj101 sortby-result]# ls
000000_0  000001_0  000002_0
[root@zjj101 sortby-result]# cat 000000_0 
7900    JAMES   CLERK   7698    1981-12-3       950.0   \N      30
7844    TURNER  SALESMAN        7698    1981-9-8        1500.0  0.0     30
7698    BLAKE   MANAGER 7839    1981-5-1        2850.0  \N      30
7654    MARTIN  SALESMAN        7698    1981-9-28       1250.0  1400.0  30
7521    WARD    SALESMAN        7698    1981-2-22       1250.0  500.0   30
7499    ALLEN   SALESMAN        7698    1981-2-20       1600.0  300.0   30
[root@zjj101 sortby-result]# cat 000001_0 
7934    MILLER  CLERK   7782    1982-1-23       1300.0  \N      10
7839    KING    PRESIDENT       \N      1981-11-17      5000.0  \N      10
7782    CLARK   MANAGER 7839    1981-6-9        2450.0  \N      10
[root@zjj101 sortby-result]# cat 000002_0 
7902    FORD    ANALYST 7566    1981-12-3       3000.0  \N      20
7876    ADAMS   CLERK   7788    1987-5-23       1100.0  \N      20
7788    SCOTT   ANALYST 7566    1987-4-19       3000.0  \N      20
7566    JONES   MANAGER 7839    1981-4-2        2975.0  \N      20
7369    SMITH   CLERK   7902    1980-12-17      800.0   \N      20
[root@zjj101 sortby-result]# 

Cluster By

当distribute by和sorts by字段相同时,可以使用cluster by方式说白了就是如果你分区的字段和排序的字段一致的话,可以简写为Cluster By

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

以下两种写法等价,我就不演示了…

  select * from emp cluster by deptno;
  select * from emp distribute by deptno sort by deptno;

今天的文章hive四种排序Order By , Sort By ,Distribute By ,Cluster By分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:http://bianchenghao.cn/25170.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注