Hive優化

hive.optimize.cp=true:列裁剪

hive.optimize.prunner:分區裁剪

hive.limit.optimize.enable=true:優化LIMIT n語句

hive.limit.row.max.size=1000000:

hive.limit.optimize.limit.file=10:最大文件數

1. 本地模式(小任務):

需要滿足以下條件:

1.job的輸入數據大小必須小于參數:hive.exec.mode.local.auto.inputbytes.max(默認128MB)

2.job的map數必須小于參數:hive.exec.mode.local.auto.tasks.max(默認4)

3.job的reduce數必須為0或者1

hive.exec.mode.local.auto.inputbytes.max=134217728

hive.exec.mode.local.auto.tasks.max=4

hive.exec.mode.local.auto=true

hive.mapred.local.mem:本地模式啟動的JVM內存大小

2. 并發執行:

hive.exec.parallel=true ,默認為false

hive.exec.parallel.thread.number=8

3.Strict Mode:

hive.mapred.mode=true,嚴格模式不允許執行以下查詢:

分區表上沒有指定了分區

沒有limit限制的order by語句

笛卡爾積:JOIN時沒有ON語句

4.動態分區:

hive.exec.dynamic.partition.mode=strict:該模式下必須指定一個靜態分區

hive.exec.max.dynamic.partitions=1000

hive.exec.max.dynamic.partitions.pernode=100:在每一個mapper/reducer節點允許創建的最大分區數

DATANODE:dfs.datanode.max.xceivers=8192:允許DATANODE打開多少個文件

5.推測執行:

mapred.map.tasks.speculative.execution=true

mapred.reduce.tasks.speculative.execution=true

hive.mapred.reduce.tasks.speculative.execution=true;

6.Single MapReduce MultiGROUP BY

hive.multigroupby.singlemar=true:當多個GROUP BY語句有相同的分組列,則會優化為一個MR任務

7. hive.exec.rowoffset:是否提供虛擬列

8. 分組

兩個聚集函數不能有不同的DISTINCT列,以下表達式是錯誤的:

INSERT OVERWRITE TABLE pv_gender_agg SELECT pv_users.gender, count(DISTINCT pv_users.userid), count(DISTINCT pv_users.ip) FROM pv_users GROUP BY pv_users.gender;

SELECT語句中只能有GROUP BY的列或者聚集函數。

9.

hive.map.aggr=true;在map中會做部分聚集操作,效率更高但需要更多的內存。

hive.groupby.mapaggr.checkinterval:在Map端進行聚合操作的條目數目

10.

hive.groupby.skewindata=true:數據傾斜時負載均衡,當選項設定為true,生成的查詢計劃會有兩個MRJob。第一個MRJob 中,

Map的輸出結果集合會隨機分布到Reduce中,每個Reduce做部分聚合操作,并輸出結果,這樣處理的結果是相同的GroupBy Key

有可能被分發到不同的Reduce中,從而達到負載均衡的目的;第二個MRJob再根據預處理的數據結果按照GroupBy Key分布到

Reduce中(這個過程可以保證相同的GroupBy Key被分布到同一個Reduce中),最后完成最終的聚合操作。

11.Multi-Group-By Inserts:

FROM test

INSERT OVERWRITE TABLE count1

SELECT count(DISTINCT test.dqcode)

GROUP BY test.zipcode

INSERT OVERWRITE TABLE count2

SELECT count(DISTINCT test.dqcode)

GROUP BY test.sfcode;

12.排序

ORDER BY colName ASC/DESC

hive.mapred.mode=strict時需要跟limit子句

hive.mapred.mode=nonstrict時使用單個reduce完成排序

SORT BY colName ASC/DESC :每個reduce內排序

DISTRIBUTE BY(子查詢情況下使用 ):控制特定行應該到哪個reducer,并不保證reduce內數據的順序

CLUSTER BY :當SORT BY 、DISTRIBUTE BY使用相同的列時。

13.合并小文件

hive.merg.mapfiles=true:合并map輸出

hive.merge.mapredfiles=false:合并reduce輸出

hive.merge.size.per.task=256*1000*1000:合并文件的大小

hive.mergejob.maponly=true:如果支持CombineHiveInputFormat則生成只有Map的任務執行merge

hive.merge.smallfiles.avgsize=16000000:文件的平均大小小于該值時,會啟動一個MR任務執行merge。

14.map/reduce數目

減少map數目:

set mapred.max.split.size

set mapred.min.split.size

set mapred.min.split.size.per.node

set mapred.min.split.size.per.rack

set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat

增加map數目:

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

假設有這樣一個任務:

select data_desc, count(1), count(distinct id),sum(case when …),sum(case when ...),sum(…) from a group by data_desc

如果表a只有一個文件,大小為120M,但包含幾千萬的記錄,如果用1個map去完成這個任務,肯定是比較耗時的,這種情況下,我們要考慮將這一個文件合理的拆分成多個,這樣就可以用多個map任務去完成。

set mapred.reduce.tasks=10;

create table a_1 as select * from a distribute by rand(123);

這樣會將a表的記錄,隨機的分散到包含10個文件的a_1表中,再用a_1代替上面sql中的a表,則會用10個map任務去完成。每個map任務處理大于12M(幾百萬記錄)的數據,效率肯定會好很多。

reduce數目設置:

參數1:hive.exec.reducers.bytes.per.reducer=1G:每個reduce任務處理的數據量

參數2:hive.exec.reducers.max=999(0.95*TaskTracker數):每個任務最大的reduce數目

reducer數=min(參數2,總輸入數據量/參數1)

set mapred.reduce.tasks:每個任務默認的reduce數目。典型為0.99*reduce槽數,hive將其設置為-1,自動確定reduce數目。

15.使用索引:

hive.optimize.index.filter:自動使用索引

hive.optimize.index.groupby:使用聚合索引優化GROUP BY操作

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容