推薦大家去看原文博主的文章,條理清晰閱讀方便,轉載是爲了方便以後個人查閱
https://blog.csdn.net/wyqwilliam/article/details/81973974
hive 核心思想:
把 Hive SQL 當做 Mapreduce 程序去優化。
以下 SQL 不會轉爲 Mapreduce 來執行:
select 僅查詢本表字段; where 僅對本表字段做條件過濾。
explain 命令可以顯示執行計劃:
EXPLAIN [EXTENDED] query; EXTENDED 可以看到更詳細 的信息。
本地模式提高執行效率
本地模式:
mapreduce 任務運行在一臺節點上,該節點把需要的資源從其他機器 copy 過來
集羣模式:
mapreduce 任務在 hadoop 集羣中執行 開啓本地模式:
set hive.exec.mode.local.auto=true;
注意:
hive.exec.mode.local.auto.inputbytes.max 默認值爲 128M,表示加載文件的最大值,若 大於該配置仍會以集羣方式來運行
查詢的數據在數據量不大的表中,這種情況使用本地模式,數據量大時使用集羣模式
並行計算
hive 執行 sql 默認是順序執行,如下 sql 如果使用並行計算會大大提高效率,但是集羣 壓力也增大:
select wc.col1,bk.col2 from
(select count(*) as col1 from wordcount) wc,
(select count(*) as col2 from bucket) bk;
兩條子查詢可以使用並行計算
通過設置以下參數開啓並行模式:
set hive.exec.parallel=true;
注意:
hive.exec.parallel.thread.number
代表一次 SQL 計算中允許並行執行的 job 個數的最大值
嚴格模式
查詢限制:
1) 對於分區表,必須添加 where 對於分區字段的條件過濾;
2) order by 語句必須包含 limit 輸出限制;
3) 限制執行笛卡爾積的查詢。
笛卡爾集中的記錄不一定正確,爲了避免笛卡爾集可以在 WHERE 中加入有效的連接條 件,實際運行環境下應該避免使用笛卡爾全集。
通過設置以下參數開啓嚴格模式:
set hive.mapred.mode=strict;(默認爲:nonstrict 非嚴格模式)
Hive 排序
Order By 對於查詢結果做全排序,只允許有一個 reduce 處理。當數據量較大時,應慎用。嚴格 模式下,必須結合 limit 來使用
Sort By 對於單個 reduce 的數據進行排序
Distribute By 分區排序,經常和 Sort By 結合使用
Cluster By 相當於 Sort By + Distribute By,
Cluster By 不能通過 asc、desc 的方式指定排序規則; 可通過 distribute by column sort by column asc|desc 的方式結合使用。
Hive join
Join 計算時,將小表(驅動表)放在 join 的左邊
Map Join:在 Map 端完成 Join(避免數據傾斜)
兩種實現方式:
1) SQL 方式,在 SQL 語句中添加 MapJoin 標記(mapjoin hint)
語法:
SELECT /*+ MAPJOIN(smallTable) */ smallTable.key, bigTable.value FROM smallTable JOIN bigTable ON smallTable.key = bigTable.key;
2) 開啓自動的 MapJoin
通過修改以下配置啓用自動的 mapjoin:
set hive.auto.convert.join = true; 該參數爲 true 時,Hive 自動對左邊的表統計量,如果是小表就加入內存,即對小表使 用 Map join
相關配置參數:
hive.mapjoin.smalltable.filesize;
大表小表判斷的閾值,如果表的大小小於該值則會被加載到內存中運行
hive.ignore.mapjoin.hint; 默認值:true;
是否忽略 mapjoin hint 即 mapjoin 標記
hive.auto.convert.join.noconditionaltask; 默認值:true;
將普通的 join 轉化爲普通的 mapjoin 時,是否將多個 mapjoin 轉化爲一 個 mapjoin
hive.auto.convert.join.noconditionaltask.size;
最多可以把幾個 mapjoin 轉化爲一個 mapjoin
Map-Side 聚合
通過設置以下參數開啓在 Map 端的聚合:
set hive.map.aggr=true;
相關配置參數:
hive.groupby.mapaggr.checkinterval:
map 端 group by 執行聚合時處理的多少行數據(默認:100000)
hive.map.aggr.hash.min.reduction:
進行聚合的最小比例,預先對 100000 條數據做聚合,若聚合之後的數據量/100000 的 值大於該配置 0.5,則不會聚合 hive.map.aggr.hash.percentmemory:
map 端聚合使用的內存的最大值
hive.map.aggr.hash.force.flush.memory.threshold:
map 端做聚合操作時 hash 表的最大可用內存,大於該值則會觸發 flush,溢寫到磁盤
hive.groupby.skewindata
是否對 GroupBy 產生的數據傾斜做優化,默認爲 false
控制 Hive 中 Map 以及 Reduce 的數量
Map 數量相關的參數:
mapred.max.split.size
一個 split 的最大值,即每個 map 處理文件的最大值
mapred.min.split.size.per.node
一個節點上 split 的最小值
mapred.min.split.size.per.rack
一個機架上 split 的最小值
Reduce 數量相關的參數:
mapred.reduce.tasks
強制指定 reduce 任務的數量
hive.exec.reducers.bytes.per.reducer
每個 reduce 任務處理的數據量
hive.exec.reducers.max
每個任務最大的 reduce 數
JVM 重用
適用場景:
1) 小文件個數過多
2) task 個數過多 頻繁的申請資源,釋放資源降低了執行效率
通過 set mapred.job.reuse.jvm.num.tasks=n; (n 爲 task 插槽個數)來設置,道理與 “池”類似。
缺點:
設置開啓之後,task 插槽會一直佔用資源,不論是否有 task 運行,直到所有的 task 即 整個 job 全部執行完成時,纔會釋放所有的 task 插槽資源。