前言
本文隶属于专栏《1000个问题搞定大数据技术体系》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢!
本专栏目录结构和参考文献请见1000个问题搞定大数据技术体系
正文
1. order by 会对所给的全部数据进行全局排序,不管来多少数据,都只启动一个reducer来处理 。
2. sort by是 局部排序,sort by会根据数据量的大小启动一到多个 reducer 来干活,并且,它会在进入 reduce 之前为每个 reducer 都产生一个排序文件 。
3. distribute by 控制 map 结果的分发,它会将具有相同字段的 map 输出分发到一个 reduce 节点上做处理 。
4. cluster by 可以理解为一个特殊的 distribute by 和 sort by 的结合,当 distribute by 和 sort by 后面所跟的列名相同时,就等同于直接使用 cluster by 跟上该列名。
但是被cluster by指定的列最终的排序结果只能是降序,而且无法指定 asc 和 desc。
补充
1. order by 全局排序
全局排序,只有一个reduce
使用 order by 子句排序
- asc (ascend)—— 升序 (默认)
- desc (descend)—— 降序
order by 子句在 select 语句的结尾
2. distribute by 分区排序
distribute by 类似 MapReduce 中 partition,采集 hash 算法,在 map 端将查询的结果中 hash 值相同的结果分发到对应的 reduce 文件中。需要结合sort by使用。
注意: Hive要求 distribute by 语句要写在 sort by 语句之前。
3. cluster by
-
当 distribute by 和 sort by 字段相同时,可以使用 cluster by 方式
-
除了 distribute by 的功能外,还会对该字段进行排序,所以 cluster by = distribute by + sort by
--以下两种写法等价
insert overwrite local directory '/home/hadoop/hivedata/distribute_sort'
select * from student distribute by score sort by score;
insert overwrite local directory '/home/hadoop/hivedata/cluster'
select * from student cluster by score;
实践
1. 查询学生的成绩,并按照分数降序排列
select * from student s order by score desc;
2. 按照别名排序
- 按照学生分数的平均值排序
select s.sid,s.tname, avg(score) as score_avg from student s group by s.sid,s.tname order by score_avg desc;
3. 多列排序
- 按照学生分数和年龄升序排序
select * from student s order by score,age;
4. 每个 MapReduce 内部排序(Sort By)局部排序
sort by:每个reducer内部进行排序,对全局结果集来说不是排序。
1、设置reduce个数
set mapreduce.job.reduces=3;
2、查看设置reduce个数
set mapreduce.job.reduces;
3、查询成绩按照成绩降序排列
select * from student s sort by s.score;
4、将查询结果导入到文件中(按照成绩降序排列)
insert overwrite local directory '/home/hadoop/hivedata/sort' select * from student s sort by s.score;
5. 先按照学生 sid 进行分区,再按照学生成绩进行排序
1、设置reduce的个数
set mapreduce.job.reduces=3;
2、通过 distribute by 进行数据的分区,将不同的 sid 划分到对应的 reduce 当中去
insert overwrite local directory '/home/hadoop/hivedata/distribute' select * from student distribute by sid sort by score;