1. 程式人生 > 其它 >HIVE中,order by、sort by、 distribute by和 cluster by區別,以及cluster by有什麼意義

HIVE中,order by、sort by、 distribute by和 cluster by區別,以及cluster by有什麼意義

HIVE中,order by、sort by、 distribute by和 cluster by區別,以及cluster by有什麼意義

1. oreder by

主要是做全域性排序。

​ 只要hive的sql中指定了order by,那麼所有的資料都會到同一個reducer進行處理(不管有多少map,也不管檔案有多少的block,只會啟動一個reducer )。但是對於大量資料這將會消耗很長的時間去執行。

​ 這裡跟傳統的sql還有一點區別:如果指定了hive.mapred.mode=strict(預設值是nonstrict),這時就必須指定limit來限制輸出條數。因為:所有的資料都會在同一個reducer端進行,資料量大的情況下可能不能出結果,那麼在這樣的嚴格模式下,必須指定輸出的條數。

2. sort by

​ 每個reduce端都會進行排序,也就是區域性有序,可以指定多個reduce。

​ 同時,如果想測試一下執行的效果,建議將輸出結果儲存到本地,並調整reduce的數量。(我設定成3個)

將查詢結果儲存到本地:

insert overwrite 
local directory '/home/data'
select * from stu sort by grade desc;

調整reduce的數量:

set mapreduce.job.reduce=3;

檢視reduce的數量:

set mapreduce.job.reduce;

但是,使用sort by的情況下,分割槽是隨機分的。

3. distribute by

指定分割槽原則。通常和sort by一起用,distribute by必須要寫在sort by之前。

理解成:按照XX欄位分割槽,再按照XX欄位排序
舉個例子:

只按照grade欄位排序,但是不指定分割槽欄位:

select * from stu sort by grade;

先按照class分割槽,再按照grade排序:

select * from stu distribute by class sort by grade;

4. cluster by

當distribute by 和 sort by 所指定的欄位相同時,即可以使用cluster by。
注意

:cluster by指定的列只能是降序,不能指定asc和desc。

​ 舉個例子:

select * from stu distribute by class sort by class

​ 等價於:

select * from stu cluster by class

---------------------------------------------分割線---------------------------------------------
再舉個例子:

select * from stu distribute by class sort by class,name

​ 等價於

select * from stud distribute cluster by class sort by name

5. cluster by有什麼意義?

​ cluster by是hive中的,mysql等資料庫中是沒有的,為什麼hive會出現cluster by呢?

order by

​ 當需要對資料排序時,我們可以使用order by。但使用order by意味著對所有資料進行排序,即:無論有多少個map,無論有多少資料量,都只用一個reduce。這會消耗極大的時間,且資料量大時,對資源消耗也極為巨大。
​ 這種情況肯定是不能忍受的,但又沒有什麼好的解決辦法,退而求其次,不要求全域性有序,只要求區域性有序,也是一種解決辦法。於是:sort by出現了。

sort by

​ 使用sort by時,會有多個reduce。每個reduce端都會進行排序,但這時,每個reduce的資料是有序的,但資料全域性上看依然是無序的。也就是區域性有序,整體無序。

distribute by

​ 使用sort by時,資料是區域性有序,整體無序。但這時候,哪些資料進入同一個reduce是隨機的,不可把控的。所以可以使用 distribute by 來指定哪些資料進入同一個reduce。
​ 也就是說,我們可以指定哪些資料進入到同一個reduce中,然後這些資料進行排序。

cluster by

​ 等價於 distribute by + sort by

舉個例子

​ 舉個栗子:某學校對學生成績進行排序。

select * from t_score order by grade
-- 因為使用了order by,只有一個reduce。 

distribute by 、 sort by

​ 假設學生太多,資料太多,無法使用order by進行全域性排序

 這時候我們可以要求學生的成績按照專業進行排序,不要求在全校內排序。即:
select * from t_score 
distribute by major sort by grade
-- 因為沒有使用order by,所以這時可以有多個reduce。 

​ 但是,如果reduce的數量小於專業的數量,就會有多個專業在一個reduce中處理的情況,這時候,如果還是distribute by major sort by grade,就會亂序。即:多個專業分到一個區,且直接按照分數排序。
​ 對於這種情況,我們需要先按照專業排序,再按照分數排序。

select * from t_score 
distribute by major sort by major, grade
-- 因為沒有使用order by,所以這時可以有多個reduce。 

其它寫法

​ 在我印象裡,之前是支援這種寫法的:

select * from t_score 
cluster by major sort by grade

但是剛才試了一下(2.幾版本的hive),不支援這種寫法。

test

CREATE TEMP VIEW person (name, age)
AS VALUES ('Zen Hui', 25),
('Anil B', 18),
('Shone S', 16),
('Mike A', 25),
('John A', 18),
('Jack N', 16);

-- Reduce the number of shuffle partitions to 2 to illustrate the behavior of CLUSTER BY.
-- It's easier to see the clustering and sorting behavior with less number of partitions.

SET spark.sql.shuffle.partitions = 2;

-- Select the rows with no ordering. Please note that without any sort directive, the results
-- of the query is not deterministic. It's included here to show the difference in behavior
-- of a query when CLUSTER BY is not used vs when it's used. The query below produces rows
-- where age column is not sorted.

SELECT age, name FROM person;
16 Shone S
25 Zen Hui
16 Jack N
25 Mike A
18 John A
18 Anil B

-- Produces rows clustered by age. Persons with same age are clustered together.
-- In the query below, persons with age 18 and 25 are in first partition and the
-- persons with age 16 are in the second partition. The rows are sorted based
-- on age within each partition.

SELECT age, name FROM person CLUSTER BY age;
18 John A
18 Anil B
25 Zen Hui
25 Mike A
16 Shone S
16 Jack N

疑問解答

“cluster by 的欄位只是參考分割槽欄位,而非嚴格的按此欄位分割槽”
可以這麼說吧,分割槽欄位的目的不是說按照其列舉值數量產生對應數量的reducer個數,而是為了讓同一個key進入同一個reducer中,這是基本的要求,是聚合的基礎

解決資料傾斜

​ distribute by可以實現打亂資料從而解決資料傾斜的效果,但是解決以後資料是無序的,使用cluster by可以在解決資料傾斜的效果之上實現區域性有序。

方便檢視輸出檔案

​ hive可以將查詢結果儲存到hdfs上,資料量太大且只有一個檔案時,檢視和傳輸都很不方便。如果按照固定的大小或條數分開儲存,又會出現資料不連貫的情況。
​ 這時候,使用cluster by,既可以生成多個檔案,又可以保證資料區域性有序且連貫。
​ 連貫的意思是:假設我看一個學校的學生的成績,重點關注專業。當人為或使用其他辦法(標準是:固定的大小或條數分開儲存)分片儲存資料時,就會出現某專業的學生出現在多個檔案中,對檢視資料很不友好。