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进行排序的时候要注意数据量的问题
2. sort by
hive中的sort by是进行的区内排序,如果指定了reduce的个数唯一,那
么排序的结果就是全局排序,如果有多个reduce就是区内有序,全局无序,
这个要根据个人的需求来使用。
使用语法如下:
select * from tb_name sort by column_name;
数据表如下:
goods | gtype | price |
口香糖 | 食品 | 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;
结果数据如下:
goods | gtype | price |
口香糖 | 食品 | 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;
结果数据如下:
goods | gtype | price | rn |
热水器 | 电器 | 102 | 1 |
空调 | 电器 | 92 | 2 |
电磁炉 | 电器 | 82 | 3 |
电暖器 | 电器 | 72 | 4 |
小太阳 | 电器 | 62 | 5 |
洗衣机 | 电器 | 52 | 6 |
冰柜 | 电器 | 42 | 7 |
冰箱 | 电器 | 32 | 8 |
电脑 | 电器 | 22 | 9 |
电视 | 电器 | 12 | 10 |
椅子 | 日用品 | 91 | 11 |
水壶 | 日用品 | 81 | 12 |
水杯 | 日用品 | 71 | 13 |
卫生纸 | 日用品 | 61 | 14 |
毛巾 | 日用品 | 51 | 15 |
拖布 | 日用品 | 41 | 16 |
洗洁精 | 日用品 | 31 | 17 |
洗衣液 | 日用品 | 21 | 18 |
洗衣粉 | 日用品 | 11 | 19 |
方便面 | 食品 | 90 | 20 |
月饼 | 食品 | 80 | 21 |
面包 | 食品 | 70 | 22 |
饼干 | 食品 | 60 | 23 |
薯条 | 食品 | 50 | 24 |
蛋糕 | 食品 | 40 | 25 |
巧克力 | 食品 | 30 | 26 |
薯片 | 食品 | 20 | 27 |
口香糖 | 食品 | 10 | 28 |
从结果数据中可以看出来从行号'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;
单独使用的结果数据如下:
goods | gtype | price |
口香糖 | 食品 | 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;
测试结果数据如下:
goods | gtype | price |
洗衣粉 | 日用品 | 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的时候一定要注意这个特点,
避免踩坑。