hive sql的優化

1. 將大表放後頭

Hive假定查詢中最後的一個表是大表。它會將其它表緩存起來,然後掃描最後那個表。

因此通常需要將小表放前面,或者標記哪張表是大表:/*streamtable(table_name) */

2. 使用相同的連接鍵

當對3個或者更多個表進行join連接時,如果每個on子句都使用相同的連接鍵的話,那麼只會產生一個MapReduce job。

3. 儘量儘早地過濾數據

減少每個階段的數據量,對於分區表要加分區,同時只選擇需要使用到的字段。

4. 儘量原子化操作

儘量避免一個SQL包含複雜邏輯,可以使用中間表來完成複雜的邏輯

5. 並行執行

hive會將一個查詢轉化爲一個或多個階段,包括:MapReduce階段、抽樣階段、合併階段、limit階段等。默認情況下,一次只執行一個階段。 不過,如果某些階段不是互相依賴,是可以並行執行的。

set hive.exec.parallel=true,可以開啓併發執行。

set hive.exec.parallel.thread.number=16; //同一個sql允許最大並行度,默認爲8。

會比較耗系統資源

6. 調整mapper和reducer的個數

6.1 Map階段優化

map個數的主要的決定因素有: input的文件總個數,input的文件大小,集羣設置的文件塊大小(默認128M,不可自定義)。

舉例:

a) 假設input目錄下有1個文件a,大小爲780M,那麼hadoop會將該文件a分隔成7個塊(6個128m的塊和1個12m的塊),從而產生7個map數

b) 假設input目錄下有3個文件a,b,c,大小分別爲10m,20m,130m,那麼hadoop會分隔成4個塊(10m,20m,128m,2m),從而產生4個map數

即,如果文件大於塊大小(128m),那麼會拆分,如果小於塊大小,則把該文件當成一個塊。

map執行時間:map任務啓動和初始化的時間+邏輯處理的時間。

1)減少map數

若有大量小文件(小於128M),會產生多個map,處理方法是:

set mapred.max.split.size=100000000;

set mapred.min.split.size.per.node=100000000;

set mapred.min.split.size.per.rack=100000000;

– 前面三個參數確定合併文件塊的大小,大於文件塊大小128m的,按照128m來分隔,小於128m,大於100m的,按照100m來分隔,把那些小於100m的(包括小文件和分隔大文件剩下的)進行合併

set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; – 執行前進行小文件合併

2)增加map數

當input的文件都很大,任務邏輯複雜,map執行非常慢的時候,可以考慮增加Map數,來使得每個map處理的數據量減少,從而提高任務的執行效率。

set mapred.reduce.tasks=?

6.2 Reduce階段優化

調整方式:

– set mapred.reduce.tasks=?

– set hive.exec.reducers.bytes.per.reducer = ?

一般根據輸入文件的總大小,用它的estimation函數來自動計算reduce的個數:reduce個數 = InputFileSize / bytes per reducer

7.嚴格模式

set hive.marped.mode=strict ------ 防止用戶執行那些可能意想不到的不好的影響的查詢

– 分區表,必須選定分區範圍

– 對於使用order by的查詢,要求必須使用limit語句。因爲order by爲了執行排序過程會將所有的結果數據分發到同一個reducer中進行處理。

– 限制笛卡爾積查詢:兩張表join時必須有on語句

8.數據傾斜

表現:任務進度長時間維持在99%(或100%),查看任務監控頁面,發現只有少量(1個或幾個)reduce子任務未完成。因爲其處理的數據量和其他reduce差異過大。

單一reduce的記錄數與平均記錄數差異過大,通常可能達到3倍甚至更多。 最長時長遠大於平均時長。

數據傾斜的原因:

1)、key分佈不均勻

2)、業務數據本身的特性

3)、建表時考慮不周

4)、某些SQL語句本身就有數據傾斜

關鍵詞 情形 後果
join 其中一個表較小,但是key集中 分發到某一個或幾個Reduce上的數據遠高於平均值
join 大表與大表 但是分桶的判斷字段0值或空值過多,這些空值都由一個reduce處理,灰常慢
group by 維度過小,某值的數量過多 處理某值的reduce灰常耗時

解決方案:
參數調節 hive.map.aggr=true

9 參考

知識星球:大數據;

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