order by、distribute by、sort by、group by、partition by

order by:全局排序

order by 會對數據進行一次全局排序,所以說,只要hive的sql中指定了order by,那麼所有的數據都會到同一個reducer進行處理(不管有多少map,也不管文件有多少的block只會啓動一個reducer)。
order by 只在一個reduce中進行,所以數據量特別大的時候效率非常低。建議在小的數據集中使用order by進行排序
可以通過設置hive.mapred.mode參數控制執行方式:

  • 若選擇strict,則order by 需要指定limit(若有分區還有指定哪個分區)
  • 若爲nostrict,則limit不是必需的

即使設置了mapreduce.job.reduces的值大於1, 使用order by,時Hive在運行MR程序時也會設置爲1覆蓋

示例:在這裏插入圖片描述

sort by:局部排序

sort by在每個reducer端都會做排序,爲每個reduce產生一個排序文件。也就是說sort by能保證局部有序(每個reducer出來的數據是有序的,但是不能保證所有的數據是有序的,除非只有一個reducer)。
使用sort by的好處是:執行了局部排序之後可以爲接下去的全局排序提高不少的效率(其實就是做一次歸併排序就可以做到全局排序了)。

sort by 的數據在進入reduce前就完成排序。
sort by 基本上不受hive.mapred.mode影響

可以通過mapreduce.job.reduces 指定reduce個數,查詢後的數據被分發到相關的reduce中。
如果使用sort by 排序,並且設置mapreduce.job.reduces>1,sort by只能保證每個reducer輸出有序,不能保證全局數據有序。

示例:
在這裏插入圖片描述
在這裏插入圖片描述
示例:
在這裏插入圖片描述
在這裏插入圖片描述

在有些情況下,你需要,這通常是爲了進行後續的聚集操作。剛好可以做這件事。因此,distribute by經常和sort by配合使用。

distribute by:分區排序

DISTRIBUTE BY是控制map的輸出在reducer是如何劃分的
DISTRIBUTE BY是控制在map端如何拆分數據給reduce端的。
DISTRIBUTE BY可以控制某個特定行應該到哪個reducer。

distribute by 採集hash算法,在map端將查詢結果中hash值相同的結果分發到對應的reduce文件中。
hive會根據distribute by後面列,對應reduce的個數進行分發,默認是採用hash算法。

注意:distribute by必須要寫在sort by之前
示例:
在這裏插入圖片描述
我們所有的deptno相同的數據會被送到同一個reducer去處理,這就是因爲指定了distribute by deptno,這樣的話就可以統計出每個部門中各個員工sal的排序了(這個肯定是全局有序的,因爲相同部門的員工會放到同一個reducer去處理)。
在這裏插入圖片描述

cluster by:簇排序

cluster by 除了distribute by 的功能外,還會對該字段進行排序,所以cluster by = distribute by +sort by 。
distribute by 和 sort by 合用就相當於cluster by,但是cluster by 不能指定排序規則爲asc或 desc ,只能是升序排列。

比如下面兩個hql語句是等價的:

insert overwrite local directory '/usr/local/test/tt'
row format delimited fields terminated by '\t'
select * from tb_emp 
distribute by deptno
sort by deptno;
--兩者功能等價
insert overwrite local directory '/usr/local/test/tt'
row format delimited fields terminated by '\t'
select * from tb_emp 
cluster by deptno;

示例:
在這裏插入圖片描述
在這裏插入圖片描述

group by

和distribute by類似 都是按key值劃分數據,都使用reduce操作
唯一不同的是,distribute by只是單純的分散數據,distribute by col – 按照col列把數據分散到不同的reduce。

group by把相同key的數據聚集到一起,後續必須是聚合操作。

示例:
在這裏插入圖片描述

partition by

通常查詢時會對整個數據庫查詢,而這帶來了大量的開銷,因此引入了partition的概念,在建表的時候通過設置partition的字段, 會根據該字段對數據分區存放,更具體的說是存放在不同的文件夾,這樣通過指定設置Partition的字段條件查詢時可以減少大量的開銷。

示例:查詢某一個人的工資並和其所在的部門的平均薪資進行對比。

select ename,sal,deptno,avg(sal) over(partition by deptno)
from tb_emp;

結果:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章