1. 程式人生 > >Hive中order by sort by distribute by cluster by用法

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