這裏咱們須要設置兩個參數:node
1.一、hive.optimize.skewjoin = true; apache
若是join 中出現了數據傾斜, 應該設置成true。緩存
1.二、set hive.skewjoin.key = 1000000; 網絡
這是join 的鍵對應的記錄條數超過這個值則會進行優化。 而這個優化的措施是: 正常只有一個 job 來執行任務的, 優化後會出現兩個 job 來執行任務。 當數據量達到1000000以上的時候, hive 會在啓動一個job , 而後將原有的數據的key 加上一個隨機數據打亂。 這樣數據就會分到不一樣的節點上去計算。最後在原有打亂的基礎上再作一次運算, 而後再啓動一個job,恢復原來的 key ,再作一次運算。app
2.一、其實maojoin的優化簡單, 就是將咱們的小表加載到緩存中, 這樣全部的節點均可以訪問到這個小表(有點像廣播變量)。jvm
怎麼樣開啓這種方式?oop
set hive.auto.convert.join = true; 性能
hive.mapjoin.smalltable.filesize 默認是25MB。 什麼意思呢? 這個值是本身判斷的, 就是當表格文件小於25MB的時候, 會自動啓動mapjoin(這個最好手動開啓)優化
手動開啓方式: select /*+ maojoin(A)*/ f.a,f.b from A t join B f on (f.a=t.b and f.ftime=20110802)spa
其中A是小表,B是大表,這樣咱們是讓join發生在map端。
注意:Mapjoin 使用的場景
一、關聯操做中的一張小表
二、不等值的鏈接操做
三、mapjoin 最好是手動操做
3.1 兩個表以相同的方式劃分分桶
3.2 兩個表的桶的個數是倍數關係
例子:
creat table order (cid int , price float) clustered by (cid) into 30 buckets;
creat table customer(cid int, price string) clustered by (cid) into 60 buckets;
select price from order t join customer s on t.cid = s.id;
4.1 優化前:select o*from order o join customer c on o.cid=d.id where o.time='2017-01-01';
優化後: select o.*from (select cid from order where time='2017-01-01') o join customer c on o.cid=c.id;
解釋:優化前是先join後在where進行過濾的; 這樣並無減輕reduce的壓力, 優化後是在mao端執行where,過濾器,而後再join的,這樣大大下降了計算量
5.一、hive.groupby.skewindata=true;
若是group by 過程當中出現數據傾斜, 應該設置成true。
5.二、set hive.groupby.maoagger.checkinterval=1000000;
group對應的鍵對應的記錄數超過這個值則會進行優化,優化方案跟上面同樣,也會運行來年各個job
6.1 分區: ‘表‘ 至關於一個大的目錄,分區就是在這個大的目錄下面建立一個個的小目錄。並且分區字段不能是表中已經存在的字段, 分區的字段不是真實存在的, 這會顯示給你看也能夠查詢, 可是不會存在於表中
分區分爲靜態分區和動態分區;
靜態分區: 就是在 建表的時候指定分區
動態分區: set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
下面這個設置的默認值是strict。 strict是避免分區字段所有都是動態的, 也就是至少一個分區字段是由指定值的。咱們通常用nonstrict,就是全部的分區字段均可以是動態的。
7.一、並行化執行:JVE執行過程當中的job是按照默認的順序來執行的,若是沒有太大的依賴關係,最好並行執行,減小執行的時間。每一個查詢被hive轉化成多個階段,有些階段關聯性不大,則能夠並行執行,減小執行時間。
set hive.exec.parallel = true;
set hive.exec.parallel.thread.numbe = 16(默認8);
7.二、本地化執行:首先開啓本地化執行: set hive.exec.model.local.auto = true;當一個job知足以下條件的時候纔會真正使用本地模式來執行。
一、job的輸入數據大小必須小於參數。
hive.exec.mode.local.auto.inputbytes.max (默認是128MB)
二、job的map數必須小於參數
hive.exec.node.local.auto.tasks.max (默認是4)
三、job的reduce必須是0或者是1
7.三、job合併輸入的小文件
在集合中面臨這樣的問題,就是集羣中有不少的小文件,這樣會啓動不少的(FileinputFormat會調用getsplit()方法對文件進行split,而split的個數決定了map的個數),並且這小文件執行的時間短,甚至尚未咱們調用資源用的時間多,形成了集羣資源的嚴重浪費。
解決: set hive.input.format = oar.apache.hadoop.hive.ql.io.CombineHiveInputForma 這樣作之後,就會把多個split分片合併成一個。 而合併的文件數由 mapred.max.split.size 限制的大小來決定
7.四、job合併輸出小文件
小文件的輸出雖然不佔用多大的磁盤空間 可是不要忘記不管多小的文件都會在HDFS的namenode上面存在一條元數據記錄下來,很浪費資源。
解決: set hive.merge.smallfiles.avgsize = 2560000000;當輸入文件平均大小小於該值。啓動新job合併文件。
7.五、JVM的重利用:
JVM的重利用是可使得JVM實例在同一個JOB中從新實用N次
方法: set mapred.reduse.jvm.num.tasks=10;
JVM的重用對hive的性能有很大的影響,特別是對小文件的場景或者是task特別多場景, 能夠有效的減小執行時間。
7.六、關於數據的壓縮:
兩種壓縮方式: 中間壓縮和最終壓縮
中間壓縮: 減小網絡傳輸的數據量, 中間壓縮, 不須要壓縮效果特別好,選擇一個節省CPU耗時的壓縮方式就行。
set hive.execc.compress.intermediate = true;
set hive.intermedia.compression.codec = org.apache.hadoop.io.compress.SnappyCode;
set hive.intermedia.compression.type = BLOCK; (按照塊進行壓縮)
hive查詢的最總輸出結果的壓縮: 這個階段能夠選擇一個壓縮效果比價好的,這樣能夠境地集羣存儲的數據量,佔用較小的空間。
set hive.exec.compress.out = true;
set mapred.output.compression.codec = org.apache.hadoop.io.compress.GzipCodec;
set hive.intermedia.compression.type = BLOCK;