目录

order by,sort by,distribute by,cluster by的区别

深入探究 order by,sort by,distribute by,cluster by 的区别,并用数据征服你。

准备工作

建表

1
2
3
4
5
6
7
8
drop table if exists wedw_dw.province_city_info;
create table wedw_dw.province_city_info(
 proinve_name string        COMMENT '省份名'
,city_name    string        COMMENT '市名'
,pc_cnt       bigint        COMMENT '人口数(单位:万)'
,in_come      decimal(16,2) COMMENT '收入(单位:亿)'
)
row format delimited fields terminated by ',';

数据准备

/images/数据准备.png
数据准备

order by

  • 升序: asc
  • 降序: desc
  • 默认升序

order by 会对输入做全局排序,因此只有一个 reducer(多个 reducer 无法保证全局有序),然而只有一个 Reducer 会导致当输入规模较大时,消耗较长的计算时间。

1
2
3
4
select 
    *
from wedw_dw.province_city_info 
order by in_come desc;
/images/orderby.png
order by

sort by

sort by 不是全局排序,其在数据进入 reducer 前完成排序,因此,如果用 sort by 进行排序并且设置 mapped.reduce.tasks > 1,则 sort by 只会保证每个 reducer的输出有序,并不保证全局有序。(全排序实现:先用 sortby 保证每个 reducer 输出有序,然后在进行 order by 归并下前面所有的 reducer 输出进行单个 reducer排序,实现全局有序。)

sort by 之前我们还有配置属性:

1
2
//配置ruduce数量
set mapreduce.job.reduces=4;
1
2
3
4
select 
    * 
from wedw_dw.province_city_info 
sort by in_come desc;
/images/sortby.png
sort by

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 的个数进行模除后,余数相同的分到一个区。1
  • Hive 要求 DISTRIBUTE BY 语句要写在 SORT BY 语句之前。
1
2
3
4
select 
    * 
from wedw_dw.province_city_info 
distribute by proinve_name;
/images/分发.png
distribute by

distribute by 经常和 sort by 配合使用。

/images/配合.png
distribute by 和 sort by 配合

cluster by

当 distribute by 和 sort by 所指定的字段相同时,即可以使用 cluster by

1
2
3
4
5
select 
    * 
from wedw_dw.province_city_info 
distribute by in_come 
sort by in_come asc;
/images/by.png
所指定的字段相同
注意
cluster by 指定的列只能是升序,不能指定 asc 和 desc。
1
2
3
4
select 
    * 
from wedw_dw.province_city_info 
cluster by in_come;
/images/cluster.png
cluster by