Hive中order by sort by distribute by cluster 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和sort by的使用場景
1、Map輸出的檔案大小不均。
2、Reduce輸出檔案大小不均。
3、小檔案過多。
4、檔案超大。
4、cluster by
cluster by 是distribute by和sort by功能的結合,cluster by只能指定倒序排列。