Fectch 抓取是指對某些狀況下的查詢沒必要使用 MapReduce 計算node
將 hive.fetch.task.conversion 設置成 more,在全局查找、字段查找、limit查找等都不走 MapReduce 數據庫
多數的 Hadoop Job 是須要 Hadoop 提供的完整的可擴展性來處理大數據集的,不過,有時 Hive 的輸入數據量是很是小的,在這種狀況下,爲查詢觸發執行任務消耗的時間可能會比實際job的執行時間要多的多,對於大多數這種狀況,Hive 能夠經過本地模式在單臺機器上處理全部的任務,對於小數據集,執行時間能夠明顯被縮短apache
將 hive.exec.mode.local.auto 設置成 true,讓 Hive 在適當的時候自動啓動這個優化併發
有時 JOIN 超時是由於某些 KEY 對應的數據太多,而相同 KEY 對應的數據都會發送到相同的 Reducer 上,從而致使內存不夠,此時咱們應該仔細分不少狀況下,這些 KEY 對應的數據是異常數據,咱們須要在 SQL 語句中進行過濾。負載均衡
有時雖然某個 KEY 爲空對應的數據不少,可是相應的數據不是異常數據,必需要包含在 JOIN 的結果中,此時咱們能夠將表中 KEY 爲空的字段賦一個隨機的值,使得數據隨機均勻地分不到不一樣的 Reducer 上。jvm
若是不指定 MapJOIN 或者不符合 MapJOIN 的條件,那麼 Hive 解析器會將 JOIN 轉換成 Common JOIN,即:在Reduce階段完成 JOIN,容易發生數據傾斜,能夠用 MapJOIN 把小表加載到內存在 Map 端進行 JOIN,避 Reducer 處理。ide
默認狀況下,Map階段同一Key數據分發給一個reduce,當一個key數據過大時就傾斜了oop
# 是否在Map端進行聚合 set hive.map.aggr = true # 在Map端進行聚合操做的條目數目 set hive.groupby.mapaggr.checkinterval = 100000 # 有數據傾斜的時候進行負載均衡 set hive.groupby.skewindata = true
當選項設定爲 true,生成的查詢計劃會有兩個 MR Job。第一個 MR Job 中,Map 的輸出結果會隨機分佈到 Reduce 中,每一個 Reduce 作部分聚合操做,並輸出結果,這樣處理的結果是相同的 Group By Key 有可能被分發到不一樣的 Reduce中,從而達到負載均衡的目的,第二個 MR Job 再根據預處理的數據結果按照 Group By Key 分佈到 Reduce中(這個過程能夠保證相同的 Group By Key 被分佈到同一個 Reduce 中),最後完成最終的聚合操做性能
數據量小的時候無所謂,數據量大的狀況下,因爲 COUNT DISTINCT 的全聚合操做,即便設定了 Reduce Task 個數,Hive 也只會啓動一個Reduce,這就形成一個 Reduce 處理的數據量太大,致使整個 Job 很難完成,通常 COUNT DISTINCT 使用先 GROUP BY 再 COUNT 的方式替換fetch
不使用笛卡爾積
禁止使用 SELECT *
對分區表Insert數據時候,數據庫自動會根據分區字段的值,將數據插入到相應的分區中,即動態分區
# 開啓動態分區功能 hive.exec.dynamic.partition=true # 設置爲非嚴格模式 hive.exec.dynamic.partition.mode=nonstrict # 在全部執行MR的節點上,最大一共能夠建立多少個動態分區,默認1000 hive.exec.max.dynamic.partitions=1000 # 在每一個執行MR的節點上,最大能夠建立多少個動態分區,該參數須要根據實際的數據來設定 hive.exec.max.dynamic.partitions.pernode=100 # 整個MR Job中,最大能夠建立多少個HDFS文件,默認100000 hive.exec.max.created.files=100000 # 當有空分區生成時,是否拋出異常。通常不須要設置 hive.error.on.empty.partition=false
當 input 的文件都很大,任務邏輯複雜,Map 執行很是慢的時候,能夠考慮增長 Map 數,來使得每一個 Map 處理的數據量減小,從而提升任務的執行效率
在 Map 執行前合併小文件,減小 Map 數:
set hive.input.format= org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
在 Map-Reduce 的任務結束時合併小文件的設置
# 在 map-only 任務結束時合併小文件 SET hive.merge.mapfiles = true; # 在Map-Reduce任務結束時合併小文件 SET hive.merge.mapredfiles = true; # 合併文件的大小,默認256M SET hive.merge.size.per.task = 268435456; # 當輸出文件的平均大小小於該值時,啓動一個獨立的Map-Reduce任務進行文件merge SET hive.merge.smallfiles.avgsize = 16777216;
# 每一個Reduce處理的數據量默認是256MB hive.exec.reducers.bytes.per.reducer=256000000 # 每一個任務最大的Reduce數,默認爲1009 hive.exec.reducers.max=1009 # 計算Reduce數的公式 N=min(hive.exec.reducers.max, 數據總量/hive.exec.reducers.bytes.per.reducer)
Hive 會將一個查詢轉化成一個或者多個階段,這樣的階段能夠是 MapReduce 階段、抽樣階段、合併階段、limit 階段,或者 Hive 執行過程當中可能須要的其餘階段,默認狀況下,Hive 一次只會執行一個階段,不過,某個特定的 job 可能包含衆多的階段,而這些階段可能並不是徹底互相依賴的,也就是說有些階段是能夠並行執行的,這樣可能使得整個 job 的執行時間縮短。不過,若是有更多的階段能夠並行執行,那麼 job 可能就越快完成。
經過設置參數 hive.exec.parallel 值爲 true,就能夠開啓併發執行。不過,在共享集羣中,須要注意下,若是 job 中並行階段增多,那麼集羣利用率就會增長。
Hive 提供了一個嚴格模式,能夠防止用戶執行那些可能意想不到的很差的影響的查詢
開啓嚴格模式須要修改 hive.mapred.mode 值爲 strict,開啓嚴格模式能夠禁止 種類型的查詢:
JVM 重用是 Hadoop 調優參數的內容,其對 Hive 的性能具備很是大的影響,特別是對於很難避免小文件的場景或 task 特別多的場景,這類場景大多數執行時間都很短。
Hadoop 的默認配置一般是使用派生來執行和任務的,這時的啓動過程可能會形成至關大的開銷,尤爲是執行的包含有成百上千任務的狀況。
重用可使得實例在同一個中從新使用屢次。
須要在 Hadoop 的 mapred-site.xml 中配置,可是有個缺點是重用次數過大,會產生大量的垃圾
<property> <name>mapreduce.job.jvm.numtasks</name> <value>10</value> <description>How many tasks to run per jvm. If set to -1, there is no limit. </description> </property>
若是用戶由於輸入數據量很大而須要執行長時間的 Map 或者 Reduce Task 的話,那麼啓動推測執行形成的浪費是很是巨大大