1. 程式人生 > >Hive知識點四(sql優化)

Hive知識點四(sql優化)

1、Hive執行(HQL、Job、Map、Reduce)、Hive表優化、Hive SQL優化、Hive Job優化、Hive Map優化、Hive Shuffle優化、Hive Reduce 優化、Hive許可權關聯。

2、查詢操作優化

      2.1、 join優化

                hive.optimize.skewjoin=true;如果是join過程出現傾斜應該設定為true

                set hive.skewjoin.key=100000;這個是join的鍵對應的記錄條數超過這個值則會進行優化

                mapjoin  set hive.auto.convert.join = true;  hive.mapjoin.smalltable.filesize預設值是25mb;select /*+mapjoin(A)*/ f.a,f.b from A t join B f on (f.a=t.a);.

      2.2、優化前:  select m.cid,u.id from order m join customer u on m.cid=u.id where m.dt = '2016-09-21';

               優化後:  select m.cid,u.id from (select cid from order where dt='2016-09-21') m join customer u on m.cid-u.id;

                mapjoin的使用場景:  1、關聯操作中有一張表非常小;2、不等值的連結操作;

      2.3、count distinct優化

                優化前: select count(distinct id ) from tablename;

                優化後: select count(1) from (select distinct id from tablename) tmp;

                               select count(1) from (select id from tablename group by id) tmp;

               set mapred.reduce.tasks=3;

               select count(1) from (select distinct city from info ) tmp;

       2.4、Reduce優化

                set mapred.reduce.tasks=10;直接設定;

                hive.exec.reducers.max預設:999;

                hive.exec.reducers.bytes.per.reducer 預設:1G;

       2.5、優化前:  select a sum(b),count(distinct c),count(distinct d) from test group by a;

                 優化後:  select a sum(b) as b,count(c) as c,count(d) as d from(

                                select a,0 as b,c,null as d from test group by a,c

                                union all

                                select a,0 as b, null as c,d from test group by a,d

                                union all

                                select a,b,null as c,null as d from test

                               )temp1 group by a;

       2.6、Group by優化

                 hive.groupby.skewwindata = true;如果是group by過程出現傾斜應該設定為true

                 set hive.groupby.mapaggr.checkinterval=100000;這個是group的鍵對應的記錄條數超過這個值則會進行優化

       2.7、bucket join

                 兩個表以相同方式劃分分桶

                 兩個表的桶個數是倍數關係

                 create table order(cid int,price float) clustered by(cid) into 32 buckets;

                 create table customer(id int,first string) clustered by(id) into 32 buckets;

                 select price from order t join customer s on t.cid = s.id;

3、Hive優化目標

      在有限的資源下,執行效率高

     常見問題:資料傾斜、map數設定、Reduce數設定等

4、檢視執行計劃

       explain [extended] hql;

5、表優化

       5.1、分割槽

                 5.1.1、靜態分割槽

                 5.1.2、動態分割槽

                              set hive.exec.dynamic.partition=true;

                              set hive.exec.dynamic.partition.mode=nonstrict;

       5.2、分桶

                 set hive.enforce.bucketing=true;

                 set hive.enfore.sorting = true;

       5.3、資料(相同資料儘量聚集在一起)

6、Hive Job優化

     6.1、 job合併輸入小檔案

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

      合併檔案數由mapred.max.split.size限制的大小決定

      job合併輸出小檔案

     set hive.merge.smallfiles.avgsize=256000000;當輸出檔案平均大小小於該值,啟動新job合併檔案

     set hive.merge.size.per.task = 64000000;合併之後的檔案大小

     6.2、併發執行

           每個查詢被hive轉化成多個階段,有些階段關聯性不大,則可以並行化執行,減少執行時間

           set hive.exec.parallel=true;

           set hive.exec.parallel.thread.number=8;

   6.3、本地化執行

           set hive.exec.mode.local.auto = true;

           當一個job滿足如下條件才能真正使用本地模式 : 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;

  6.4、JVM重利用

            set mapred.job.reuse.jvm.num.tasks=20;

            jvm重利用可以是job長時間保留slot,且到作業結束,這在對於有較多工和較多小檔案的任務是非常有意義的,減少執行時間。當然這個值不能設定過大,因為有些作業會有reduce任務,如果reduce任務沒有完成,則map任務佔用的slot不能釋放,其他的作業可能就不要等待。

  6.5、壓縮資料

            中間壓縮就是處理hive查詢的多個job之間的資料中間壓縮,最好選擇一個節省cpu耗時的壓縮方式

            set hive.exec.compress.intermediate=true;

            set hive.intermediate.compression,codec=org.apache.hadoop.io.compress.SnappyCodec;

            set hive.intermediate.compression.type=BLOCK;

            hive查詢最終的輸出也可以壓縮

             set hive.exec.compress.output = true;

             set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;

             set mapred.output.compression.type=BLOCK;

  7、Hive Map優化

        set mapred.map.tasks=10;無效

        7.1、預設map個數 default_num = total_size/block_size;

        7.2、期望大小 goal_num = mapred.map.tasks;

        7.3、設定處理的檔案大小

                 split_size = max(mapred.min.split.size,block_size);

                 split_num = total_size/split_szie;

         7.4、計算的map個數

                  compute_map_num = min(split_num,max(default_num, goal_num));

         7.5、map端聚合 set hive.map.aggr=true;

                   推測執行mapred.map.tasks.speculative.execution

         經過以上的分析,在設定map個數的時候,可以簡單的總結為以下幾點:

                  (1)、如果想增加map個數,則設定mapred.map.tasks為一個較大的值。

                  (2)、如果想減小map個數,則設定mapred.map.split.size為一個較大的值

                   情況1、輸入檔案size巨大,但不是小檔案 增大mapred.min.split.size的值

                   情況2、輸入檔案數量巨大,且都是小檔案,就是單個檔案的size小於blocksize。這種情況通過增大mapred.min.split.size不可行,需要使用

                                 CombineFileInputFormat將多個input path合併成一個InputSplit送給mapper處理,從而減少mapper的數量。

  8、Hive reduce優化

        8.1、需要reduce操作的查詢

                 聚合函式 sum,count,distinct...

                 高階查詢 group by ,join,distribute by ,cluster by...

                                  order by 比較特殊,只需要一個reduce

        8.2、推測執行

                  mapred.reduce.tasks.speculative.execution

                  hive.mapred.reduce.tasks.speculative.execution

        8.3、set mapred.reduce.tasks=10;直接設定

                   hive.exec.reducers.max 預設:999

                   hive.exec.reducers.bytes.per.reducer 預設:1G

        8.4、計算公式

                  numRTasks = min[maxReducers,input.size/perReducer]

                  maxReducers = hive.exec.reducers.max

                  perReducer = hvie.exec.reducers.bytes.per.reducer