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只能指定倒序排列。