Hive中的排序方法:sort by、order by、distribute by和cluster by

在Hive中,像SQL一样,可以根据全局排序和分布要求决定对数据进行全局排序或局部排序。在这篇文章中,将对Hive中的SORT BY,ORDER BY,DISTRIBUTE BY和CLUSTER BY做对比。

sort by

sort by不是全局排序,其在数据进入reducer前完成排序,因此,如果用sort by进行排序,并且设置mapred.reduce.tasks>1则sort by只会保证每个reducer的输出有序,并不保证全局有序。 sort by不同于order by,它不受Hive.mapred.mode属性的影响,sort by的数据只能保证在同一个reduce中的数据可以按指定字段排序。使用sort by你可以指定执行的reduce个数(通过set mapred.reduce.tasks=n来指定),对输出的数据再执行归并排序,即可得到全部结果。

sort by排序顺序将取决于列类型。如果该列是数字类型,那么排序顺序也是按数字顺序排列的。如果该列是字符串类型,那么排序顺序将是字典顺序。

举例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
hive> SELECT emp_id, emp_salary FROM employees SORT BY emp_salary DESC;

reduce 1
emp_id | emp_salary
10             5000
16             3000
13             2600
19             1800
reduce 2
emp_id | emp_salary
11             4000
17             3100
14             2500
20             2000

order by

hive中的order by 跟传统的sql语言中的order by作用一样,会对查询结果做一次全局排序,所以说,hive的sql中所有数据都会到同一个reduce中进行处理(不管有多少map,也不管有多少的block都只会启动一个reducer)。 但是对于大量数据这将耗费很长时间去执行。

这里跟传统的sql还有一点区别:如果指定了hive.mapred.mode=strict(默认是nonstrict),这时就必须指定limit来限制输出条数,原因是:所有的数据都会在同一个reducer端进行,数据量大的情况下可能不会出来结果,在严格模式下必须指定输出条数。

distribute by

distribute by是控制在map端如何拆分数据给reduce端的。hive会根据distribute by后面列,对应reduce的个数进行分发,默认是采用hash算法。 sort by为每个reduce产生一个排序文件。在有些情况下,你需要控制某个特定行应该到哪个reducer,这通常是为了进行后续的聚集操作。distribute by刚好可以做这件事。因此,distribute by经常和sort by配合使用。
distribute by和sort by的应用场景:

  • Map输出的文件大小不均。
  • Reduce输出文件大小不均。
  • 小文件过多。
  • 文件超大。

举例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
根据年份和气温对气象数据进行排序,以确保所有具有相同年份的行最终都在一个reducer分区中。
$ cat distribute/000000_0
2016,23.0
2016,39.9
2016,32.0
2013,34.0
$ cat distribute/000001_0
2008,32.0
2008,21.0
2008,31.5
2008,17.0
$ cat distribute/000002_0
2015,31.0
2015,19.9
2015,27.0
2015,32.0
2015,33.0
2015,15.9
二者结合使用
select * from temperature distribute by year sort by year asc, temper desc;
2013 34.0
2016 39.9
2016 32.0
2016 23.0
2008 32.0
2008 31.5
2008 21.0
2008 17.0
2015 33.0
2015 32.0
2015 31.0
2015 27.0
2015 19.9
2015 15.9

cluster by

cluster by除了具有distribute by的功能外还兼具sort by的功能。但是排序只能是倒叙排序,不能指定排序规则为ASC或者DESC。

使用cluster by来完场上述例子,只需要一行:

1
select * from cluster by year;

本文作者:Qiu Qingyu
版权声明:本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 CN许可协议。转载请注明出处!
本文永久链接:http://qiuqingyu.cn/2019/01/23/Hive中的排序方法:sort by、order by、distribute by和cluster by/