Hive中的order by跟傳統的sql語言中的order by作用是一樣的,會對查詢的結果做一次全局排序,所以說,只有hive的sql中制定了order by所有的數據都會到同一個reducer進行處理(不管有多少map,也不管文件有多少的block只會啓動一個reducer)。但是對於大量數據這 將會消耗很長的時間去執行。
這裏跟傳統的sql還有一點區別:如果指定了hive.mapred.mode=strict(默認值是nonstrict),這時就必須指定limit 來限制輸出條數,原因是:所有的數據都會在同一個reducer端進行,數據量大的情況下可能不能出結果,那麼在這樣的嚴格模式下,必須指定輸出的條數。
所以數據量大的時候能不用order by就不用,可以使用sort by結合distribute by來進行實現。sort by是局部排序,而distribute by是控制map怎麼劃分reducer。
Hive中指定了sort by,那麼在每個reducer端都會做排序,也就是說保證了局部有序(每個reducer出來的數據是有序的,但是不能保證所有的數據是有序的,除非只有一個reducer),好處是:執行了局部排序之後可以爲接下去的全局排序提高不少的效率(其實就是做一次歸併排序就可以做到全局排序了)
ditribute by是控制map的輸出在reducer是如何劃分的,舉個例子,我們有一張表,mid是指這個store所屬的商戶,money是這個商戶的盈利,name是這個store的名字
store:
mid |
money |
name |
AA |
15.0 |
商店1 |
AA |
20.0 |
商店2 |
BB |
22.0 |
商店3 |
CC |
44.0 |
商店4 |
執行hive語句:
select mid, money, name from store distribute by mid sort by mid asc, money asc
我 們所有的mid相同的數據會被送到同一個reducer去處理,這就是因爲指定了distribute by mid,這樣的話就可以統計出每個商戶中各個商店盈利的排序了(這個肯定是全局有序的,因爲相同的商戶會放到同一個reducer去處理)。這裏需要注意 的是distribute by必須要寫在sort by之前。
cluster by
cluster by的功能就是distribute by和sort by相結合,如下2個語句是等價的:
select mid, money, name from store cluster by mid
select mid, money, name from store distribute by mid sort by mid
如果需要獲得與上面的中語句一樣的效果:
select mid, money, name from store cluster by mid sort by money
注意被cluster by指定的列只能是降序,不能指定asc和desc。