hive 各种by相关的介绍

1、order by

hive中的order by和传统sql中的order by 一样,会对数据做全局排序,加上排序,会新启动一个jod进行排序,会把所有数据放到同一个reduce中进行处理,不管数据多少,
不管文件多少,都启用一个reduce进行处理。
注意:
(1):order by后面可以有多列进行排序,默认按字典排序
(2):order by为全局排序
(3):order by需要reduce操作,且只有一个reduce,无法配置(因为多个reduce无法完成全局排序)。
order by操作会受到如下属性的制约
1、set hive.mapred.mode=nonstrict;
2、set hive.mapred.mode=strict;
注:如果在strict模式下使用order by语句,那么必须要在语句上加上limit关键字,因为执行order by的时候只能启动单个reduce,如果排序的结果集过大,那么执行时间会非常漫长
如:原始数据为
id money name
2 15 d
2 13 b
4 13 g
1 14 c
1 12 a
3 11 h
3 14 f
select id,sum(money) from t group by id 这条语句只用一个job就ok,
select id,sum(money) from t group by id order by id 如果加上order by 就会多一个job进行排序操作

2、sort by

sort by是局部排序,会在每个reduce端做排序,每个reduce端是排序的,也就是每个reduce出来的数据是有序的,但是全部不一定有序,除非一个reduce,一般情况下可以先进行局部排序完成后,再进行全局排序,会提高不少效率。

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

select id,sum(money) from t group by id sort by id; 这条语句也不会增加job,它在reduce端直接进行排序。

3、distribute by

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

将数据打乱,避免数据倾斜的一个方式
distribute by pmod(cast(rand()*1000 as int),50);
注:Distribute by和sort by的使用场景
1、Map输出的文件大小不均。
2、Reduce输出文件大小不均。
3、小文件过多。
4、文件超大。

4、cluster by

cluster by 是distribute by和sort by功能的结合,cluster by只能指定倒序排列。

5、partition by

partition by关键字是分析性函数的一部分,它和聚合函数(如group by)不同的地方在于它能返回一个分组中的多条记录,而聚合函数一般只有一条反映统计值的记录,
partition by用于给结果集分组,如果没有指定那么它把整个结果集作为一个分组。
partition by 与group by不同之处在于前者返回的是分组里的每一条数据,并且可以对分组数据进行排序操作。后者只能返回聚合之后的组的数据统计值的记录。

6、Does anyone know what

*rank() over(distribute by p_mfgr sort by p_name) *

does exactly and how it’s different from

rank() over(partition by p_mfgr order by p_name)?

DISTRIBUTE BY user, SORT BY score DESC

then RANK(user) on that

The UDF would just give a different rank for each row within the same user
group, but it can’t give the same rank for different rows in the same user
group that have the same score. (

Hive’s rank() OVER PARTITION BY seems to support this in the iterate()
method. Also, the function is applied to a single partition (in this case,
per user group), as opposed to a single reducer that may see different
partitions, and the prev/current row comparison is done on the PARTITION BY
columns.