hive中order by、sort by、distribute by、cluster by的区别详解

1. order by

  在hive中order by是进行全局排序的,这也就是说会最后会在一个reduce
中进行统一的排序,所以说使用order by进行全局排序尽量不要对数据量很
大 的表进行全局排序,这样效率会很低,会对进行排序的那一个reduce所在
的节点造成内存压力。
使用order by会受到如下属性的约束:
set hive.mapred.mode=nonstrict;
set hive.mapred.mode=strict;
  默认是在nonstrict模式下的,如果在strict模式下使用order by的话必
须使用limit关键字,这里只是讲解一下order by的排序是在哪里进行的,
就不举例子说明了,总之使用order by进行排序的时候要注意数据量的问题
具体的使用规则在之前的文章中已经进行了讲解,如果有想要了解的可通过
如下网址看一下:

order by详细讲解

2. sort by

  hive中的sort by是进行的区内排序,如果指定了reduce的个数唯一,那
么排序的结果就是全局排序,如果有多个reduce就是区内有序,全局无序,
这个要根据个人的需求来使用。
使用语法如下:
select * from tb_name sort by column_name;
数据表如下:
goodsgtypeprice
口香糖食品10
薯片食品20
巧克力食品30
蛋糕食品40
薯条食品50
饼干食品60
面包食品70
月饼食品80
方便面食品90
洗衣粉日用品11
洗衣液日用品21
洗洁精日用品31
拖布日用品41
毛巾日用品51
卫生纸日用品61
水杯日用品71
水壶日用品81
椅子日用品91
电视电器12
电脑电器22
冰箱电器32
冰柜电器42
洗衣机电器52
小太阳电器62
电暖器电器72
电磁炉电器82
空调电器92
热水器电器102
先将reduce的个数设置为1
set mapred.reduce.tasks=1;
结果数据如下:
goodsgtypeprice
口香糖食品10
洗衣粉日用品11
电视电器12
薯片食品20
洗衣液日用品21
电脑电器22
巧克力食品30
洗洁精日用品31
冰箱电器32
蛋糕食品40
拖布日用品41
冰柜电器42
薯条食品50
毛巾日用品51
洗衣机电器52
饼干食品60
卫生纸日用品61
小太阳电器62
面包食品70
水杯日用品71
电暖器电器72
月饼食品80
水壶日用品81
电磁炉电器82
方便面食品90
椅子日用品91
空调电器92
热水器电器102
从结果可以看出来当将reduce的个数设置为1的时候,使用sort by进
行排序结果是全局有序的。

现在将reduce的个数设置为3
set mapred.reduce.tasks=3;
结果数据如下:
goodsgtypepricern
热水器电器1021
空调电器922
电磁炉电器823
电暖器电器724
小太阳电器625
洗衣机电器526
冰柜电器427
冰箱电器328
电脑电器229
电视电器1210
椅子日用品9111
水壶日用品8112
水杯日用品7113
卫生纸日用品6114
毛巾日用品5115
拖布日用品4116
洗洁精日用品3117
洗衣液日用品2118
洗衣粉日用品1119
方便面食品9020
月饼食品8021
面包食品7022
饼干食品6023
薯条食品5024
蛋糕食品4025
巧克力食品3026
薯片食品2027
口香糖食品1028
  从结果数据中可以看出来从行号'rn'的1~10中的数据是有序的,11~19
中的数据是有序的,20~28中的数据是有序的都是倒序,但是全局是无序的,
所以在使用sort by的时候一定要根据需求来使用,否则最后的结果可能并
不是我们想要的结果。

3. distribute by

  在hive中distribute by是控制map中的数据是如何分发的,使用的hash
计算,使用distribute by指定字段就可以使map端按照执行的字段进行hash
分区,相同的key可以被分到一个reduce中,但是单独使用distribute by
不能保证数据是有序的,所以一般配合sort by来使用。

单独使用语法如下:
select * from tb_name distribute by column_name;
单独使用的结果数据如下:
goodsgtypeprice
口香糖食品10
薯片食品20
巧克力食品30
蛋糕食品40
薯条食品50
饼干食品60
面包食品70
月饼食品80
方便面食品90
毛巾日用品51
椅子日用品91
水壶日用品81
水杯日用品71
卫生纸日用品61
拖布日用品41
洗洁精日用品31
洗衣液日用品21
洗衣粉日用品11
热水器电器102
电脑电器22
冰箱电器32
冰柜电器42
洗衣机电器52
小太阳电器62
电视电器12
电暖器电器72
电磁炉电器82
空调电器92
很清晰的可以看出在电器商品类中的价格是无序的。

配合sort by使用的如法如下:
select 
  * 
from tb_name
distribute by column_name1 
sort by column_name2;
  语法中的字段名字"column_name1"和"column_name2"是可以不相同的,
也可以是相同的,这个要看在使用distribute byf分区之后想要根据哪个
字段进行sort by排序。
  这里的结果数据就不展示了,不同分区中的数据肯定是有序的,展示的意
义不大。

cluster by

  hive中的cluster的作用其实就相当与distribute by和sort by结合使
用,不过使用cluster by不能指定排序规则(asc,desc),只能是升序排序,
同时在使用cluster by进行排序的时候没办法像distribute by和sort by
的组合那样可以灵活的指定在分区后根据哪个字段进行排序。
  相信这个时候我们有这样的一个疑问"cluster by存在意义是什么?使用
某个字段分区,再根据这个字段排序意义在哪里?",当这个字段中的数据
值的种类大于分区数的时候就有意义了,就拿我的测试数据举例,假如商品
的种类有1000种,但 reduce的个数只有30个,这个时候cluser by的使用
就有意义了,相信说到这里大家应该都能明白了。

使用语法如下:
select * from tb_name cluster by column_name;
  在这里要跟大家说一下,如果在cluster by后面添加了多个字段,那么在
分 区的时候就会根据这几个字段和reduce的个数来计算hash了分区,如果
在使用cluster by的时候一定要注意这个特点。

在这给大家举个测试的例子,测试sql如下:
select * from t_test cluster by gtype,price;
测试结果数据如下:
goodsgtypeprice
洗衣粉日用品11
拖布日用品41
水杯日用品71
电视电器12
冰柜电器42
电暖器电器72
热水器电器102
口香糖食品10
蛋糕食品40
面包食品70
洗衣液日用品21
毛巾日用品51
水壶日用品81
电脑电器22
洗衣机电器52
电磁炉电器82
薯片食品20
薯条食品50
月饼食品80
洗洁精日用品31
卫生纸日用品61
椅子日用品91
冰箱电器32
小太阳电器62
空调电器92
巧克力食品30
饼干食品60
方便面食品90
  通过结果数据可以看到,这个分区似乎有些乱了,但是仔细看看数据的
话可以看出来这是根据gtype和price两个字段分区结果,就拿"日用品",
这个种类举例子,我们看一下结果表中的前三个日用品后面的价格,可
以看到,分别是"11,41,71",在看看中间部分的日用品的价格分别是"21,
51,81",最后面三个日用品的价格是"31,61,91",大家可以发现这三组价格
中的数据组内和3取模得到的结果都是一样的,组间取模都是不同的,所以
可以很清晰看出是将"日用品"类的商品分散到了三个reduce中进行排序的。
  举这个例子是为了让大家在使用cluster by的时候一定要注意这个特点,
避免踩坑。
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值