这里写目录标题
- 1、order by
- 2、sort by
- 3、 distribute by
- 4、 cluster by
- 5、总结
1、order by
order by 顾名思义就是全局排序,在hive中无论设置几个job,最后的输出结果一定是一个job。
字段说明:
empno : 员工ID
ename: 员工名字
ejob: 职位
mgr: 领导ID
hiredate: 聘用日期
sal: 工资
comm: 奖金
deptno:部门ID
统一设置好分区数量3
需求:按照员工的工资(sal)升序排序
然后我们保存到本地来查看排序后的结果,注意我们是想要看order by 有几个分区。
从最后的输出结果来看输出结果为一个分区,并且员工的信息按照工资的升序排序。
2、sort by
sort by 可以叫局部排序,好听点叫区排序。所谓区排序,就是根据某一个分区进行排序。
例如: 根据员工工资查看员工信息。
从上面的结果来看,sortby对将表分成了3个部分(分区),每个部分(分区)内工资都是升序排序。因此sort by是有几个分区就输出几个分区,并常用来作为局部排序。
3、 distribute by
distribute by并不是分区排序,它仅仅是用来分区,当然它仍然依赖设置的job的数量,并不会凭空多产生一个分区。注意事项:当为了实现分区排序的时候,distribute by要在sort by的前面
例如:根据部门的ID进行分区
可以看到,每个部门在一个分区内,但是这里需要注意的是,我的初始数据只有10,20,30这三个部门
为了继续探究hive如何进行分区的,我们插入一条新数据进入emp表中。
然后再次根据部门ID进行分区。
分区的数量依然是设置的个数,但是我们发现新插入的部门被划分到了第一个分区(0),这是为什么呢?
原因在于hive的distribute by用来控制map输出结果的分发,即map端如何拆分数据给reduce端。 会根据distribute by 后边定义的列,根据reduce的个数进行数据分发,默认是采用hash算法求解分区。也就是说对求解的hash值取模。我们只需知道,设置几个job分区,分区后就仍然会产生相同的分区即可。
注意,这里我插入了一条新的数据,但是我现在想删除,我只想进行这个3个部门的员工信息筛选,根据已有知识,我使用了
insert overwrite table emp select * from emp where deptnp!=0;
进行删除,因为目前没有找到直接删除某一行的方法,因此删除数据起始也就是筛选数据,上面的hive语句就是说插入select的结果覆盖掉原表。
完整的分区排序:
按照部分对每个员工的ID进行排序(默认降序)
根据结果显示,每个分区就都有相同的部门ID,并且员工的ID降序排列。
4、 cluster by
cluster by其实很好理解,就是说根据同一列先分区再排序。本质上是distribute by + sort by 的结合,但是没有分区排序那么灵活,单单从查询上面来看。
注意:cluster by(簇排序)排序只能是升序,不能指定排序的规则为ASC和DESC。
例如:
select * from emp cluster by deptno;
等价于
select * from emp distribute by deptno sort by deptno;
5、总结
学完hive的排序算法,单单从语法上讲,着重需要灵活运用distribute by + sort by,因为可以实现许多的功能,而order by 作为全局排序依然有很大的作用,只有cluter by 看起来比较鸡肋。还有一点是hive作为大数据仓库,其job的设置与我们的排序结果紧密联系,要清楚的知道order by的结果与分区数量无关,而sort by + cluster by + distribute by 都与我们的job相关。