Hive中 Order by,Sort by, Distribute by, Cluster by详解

Hive中 Order by,Sort by, Distribute by, Cluster by详解

本文的数据基础:
在这里插入图片描述

empnoenamejobmgrhiredatesalcommdeptno
工号姓名职位老板工号雇佣日期工资不重要部门编号

初始计算引擎为tez,而不是默认的MR。

1.Order by

order by的用法和mysql中一模一样,是针对全局排序。此处不进行详述。

2.Sort by

Hive基于Hadoop集群,Sort by为每个reducer产生一个排序文件。每个Reducer内部进行排序,对全局结果集来说不是排序。

既然是说为每个reducer产生一个排序文件,那当然要有两个以上的reducer了。可在hive客户端设置reducer个数,我这里设置为3,意味着会产生三个分区。

注意:不设置这个参数的话,默认reducer个数为1,和order by没区别。

hive (default)> set mapreduce.job.reduces=3;

针对部门编号deptno来一下sort by;

select * from emp sort by deptno desc;

在这里插入图片描述

可以看到,上表确实是被分成了三部分,并按大到小排序。

看到这三个分区,有没有什么疑问呢?为何每个分区都会有相同的deptno数据。这个结果说明分区机制并不是按照hadoop中取key的hash值 % reducer个数得到的。下面来看一段英文:

Note: It may be confusing as to the difference between 
SORT BY alone of a single column and CLUSTER BY. 
The difference is that CLUSTER BY partitions by the field and 
SORT BY if there are multiple reducers partitions randomly 
in order to distribute data (and load) uniformly across the reducers.
替你们翻译一下:
注意:关于单个列的单独SORT BY与CLUSTER BY之间的区别可能会造成混淆。 
区别在于,如果有多个reducer分区,则CLUSTER BY按字段划分,
而SORT BY则是随机划分,以便在reducer上均匀地分布数据(和负载)。

上面这段英文来自hive.apache.org官网

https://cwiki.apache.org/confluence/display/Hive/LanguageManual+SortBy

这说明结果的由来是随机的,但并不是每次都是随机,而是通过一种随机算法计算得到,就是说你再排序一次,得到的依然是上面的结果,不信的童鞋可以试一下。

sort by通常和下面要介绍的Distribute by一起使用。

3.Distribute by

Distribute by可以控制某个特定行应该到哪个reducer,通常是为了进行后续的聚集操作。类似MR中partition(自定义分区)。

先给个结论:

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

下面开搞:

依然设置reducer个数为3:

hive (default)> set mapreduce.job.reduces=3;

再针对deptno字段进行distribute by.

select * from emp distribute by deptno;

结果如下:


结果有点出人意料,数字的hash值是其本身,按照distribute by的分区规则,那应该是10在1号分区,20在2号分区,30在0号分区(请忽略null,脏数据)。这里为什么只有两个分区,20,30堆在一起了?我们来验证一下是否是真的堆在一起了,将查询的文件输出到本地:

insert overwrite local directory '/opt/module/hive/datas/dis_by' select * from emp distribute by deptno;

查看datas文件夹:

[shy@hadoop dis_by]$ ll
总用量 8
-rw-r--r--. 1 shy shy 546 7月  30 22:21 000000_0
-rw-r--r--. 1 shy shy 139 7月  30 22:21 000001_0

确实是只有两个文件,内容:

[shy@hadoop dis_by]$ cat 000000_0 
\N\N\N\N\N\N\N\N
7902FORDANALYST75661981-12-33000.0\N20
7900JAMESCLERK76981981-12-3950.0\N30
7876ADAMSCLERK77881987-5-231100.0\N20
7844TURNERSALESMAN76981981-9-81500.00.030
7788SCOTTANALYST75661987-4-193000.0\N20
7698BLAKEMANAGER78391981-5-12850.0\N30
7654MARTINSALESMAN76981981-9-281250.01400.030
7566JONESMANAGER78391981-4-22975.0\N20
7521WARDSALESMAN76981981-2-221250.0500.030
7499ALLENSALESMAN76981981-2-201600.0300.030
7369SMITHCLERK79021980-12-17800.0\N20

确实是20, 30堆在一起了。

这是因为目前用的计算引擎是tez!它会自动进行优化。

现在我们来更改一下引擎:

set hive.execution.engine=mr;

再执行一次distribute by排序:

select * from emp distribute by deptno;

结果很明确:

在这里插入图片描述

可以再加上sort by,分区内的empno进行排序:

select * from emp distribute by deptno sort by empno;

结果:
在这里插入图片描述

所以,distribute by和sort by的区别是一个按规则分区,一个随机分区并排序。

4.Cluster by

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

以下两种写法等价

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

hive (default)> select * from emp distribute by deptno sort by deptno;
rby方式。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值