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的时候一定要注意这个特点,
避免踩坑。