日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HIVE 优化浅谈

發布時間:2023/12/20 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HIVE 优化浅谈 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

HIVE 優化淺談

hive不怕數據量大,導致運行慢的主要原因是數據傾斜。hive的運行機制這里就不再贅述,咱們直入正題,聊一下hive的優化方法。

優化點一:業務邏輯優化

1.去除冗余邏輯

??對于復雜業務邏輯來說,在非數據傾斜的情況下,最有效的優化方式就是對業務邏輯的優化,去掉冗余的邏輯過程或無用的中間過程,能一步完成的不要分兩步。尤其對于舊邏輯優化及數據遷移工作中較為常見。

2.重復邏輯落臨時表

復雜的業務場景很可能會有復用的邏輯,把重復的邏輯落入臨時表中不僅能減少資源消耗,還能有利于后期的代碼維護。

優化點二:配置合理的參數

1.在hive-site.xml里面有個配置參數叫:

hive.fetch.task.conversion
配置成more,簡單查詢就不走map/reduce了,設置為minimal,就任何簡單select都會走map/reduce;

2.其他見優化點九、十、十四

優化點三:設置合理的map reduce的task數量

1. map task數量設置

mapred.min.split.size: 指的是數據的最小分割單元大小;min的默認值是1B mapred.max.split.size: 指的是數據的最大分割單元大小;max的默認值是128MB 通過調整max可以起到調整map數的作用:減小max可以增加map數,增大max可以減少map數。 *注意*:直接調整mapred.map.tasks這個參數是沒有效果的。

??因為map任務啟動和初始化的時間遠遠大于邏輯處理的時間,如果map數過多,就會造成很大的資源浪費,同時可執行的map數是受限的,這樣就會造成運行過慢。如果map數過少,一個map要處理上千萬行的數據也肯定沒有多個map并行處理的快,這種情況也需要優化。所以我們需要合理地調整map數。

1.1 減少map數

??如果數據中有大量文件,每個文件都遠小于128M,為避免每個小文件開啟一個map程序,我們可以通過如下配置合并小文件,從而減少map數:

set mapred.max.split.size=100000000;(100M) set mapred.min.split.size.per.node=100000000;(100M) set mapred.min.split.size.per.rack=100000000;(100M) set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;

其中:set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;表示執行前進行小文件合并,
前面三個參數確定合并文件塊的大小,大于文件block大小128m的,按照128m來分隔;小于128m,大于100m的,按照100m來分隔;把那些小于100m的(包括小文件和分隔大文件剩下的)進行合并。

1.2 增加map數

??當input的文件都很大,任務邏輯復雜或者字段少造成行數過多,map執行非常慢的情況下,可以考慮增加Map數,來減少每個map的任務量,從而提高執行效率。

2. reduce task數量設置

??Reduce的個數對整個作業的運行性能有很大影響。如果Reduce數量設置的過多,那么將會產生很多小文件,對NameNode會產生一定的影響,而且整個作業的運行時間未必會減少;如果Reduce設置的過小,那么單個Reduce處理的數據將會加大,很可能會引起OOM異常。
如果設置了mapred.reduce.tasks/mapreduce.job.reduces參數,那么Hive會直接使用它的值作為Reduce的個數;如果mapred.reduce.tasks/mapreduce.job.reduces的值沒有設置(也就是-1),那么Hive會根據輸入文件的大小估算出Reduce的個數。根據輸入文件估算Reduce的個數可能未必很準確,因為Reduce的輸入是Map的輸出,而Map的輸出可能會比輸入要小,所以最準確的數根據Map的輸出估算Reduce的個數。
??不指定reduce個數的情況下,Hive會基于以下兩個設定reduce個數:

  參數1:hive.exec.reducers.bytes.per.reducer(每個reduce任務處理的數據量,默認為1000^3=1G)參數2:hive.exec.reducers.max(每個任務最大的reduce數,默認為999

計算reducer數的公式很簡單N=min(參數2,總輸入數據量/參數1)
  即,如果reduce的輸入(map的輸出)總大小不超過1G,那么只會有一個reduce任務;

2.1 注意 1:reduce個數并不是越多越好;

??同map一樣,啟動和初始化reduce也會消耗時間和資源;
  另外,有多少個reduce,就會有個多少個輸出文件,如果生成了很多個小文件,那么如果這些小文件作為下一個任務的輸入,則也會出現小文件過多的問題;

2.2 注意2 :有的邏輯只會產生一個reduce

只有一個reduce的情況也比較多,一種情況是數據量比較少,這種當然無需優化。但有的時候我們會發現不管數據量多大,無論怎么調整reduce個數的參數,任務中一直都只有一個reduce任務,例如:

  • 沒有group by的匯總,比如:
  • select pt,count(1) from a where pt = '20220215' group by pt; -- 多個reduce select count(1) from a where pt = '20220215'; -- 單個reduce
  • 用了全局排序:Order by
  • 有笛卡爾集
  • 3.小文件合并

    ??小文件數目過多,容易在文件存儲端造成瓶頸,給HDFS帶來壓力,影響處理效率。對此,可以通過合并Map和Reduce的結果文件來消除這樣的影響。
    用于設置合并的參數有:

    是否合并Map輸出文件:hive.merge.mapfiles=true(默認值為true) 是否合并Reduce端輸出文件:hive.merge.mapredfiles=false(默認值為false) 合并文件的大小:hive.merge.size.per.task=256*1000*1000(默認值為256000000

    小文件是如何產生的
    1.動態分區插入數據,產生大量的小文件,從而導致map數量劇增;
    2.reduce數量越多,小文件也越多(reduce的個數和輸出文件是對應的);
    3.數據源本身就包含大量的小文件。
    小文件問題的影響
    1.從Hive的角度看,小文件會開很多map,一個map開一個JVM去執行,所以這些任務的初始化,啟動,執行會浪費大量的資源,嚴重影響性能。
    2.在HDFS中,每個小文件對象約占150byte,如果小文件過多會占用大量內存。這樣NameNode內存容量嚴重制約了集群的擴展。
    小文件問題的解決方案
    從小文件產生的途徑就可以從源頭上控制小文件數量,方法如下:
    1.使用Sequencefile作為表存儲格式,不要用textfile,在一定程度上可以減少小文件;
    2.減少reduce的數量(可以使用參數進行控制);
    3.少用動態分區,用時記得按distribute by分區,distribute by 可以控制分發到reduce的方式,避免數據傾斜。
    對于已有的小文件,我們可以通過以下幾種方案解決:
    1.使用hadoop archive命令把小文件進行歸檔;
    2.重建表,建表時減少reduce數量;
    3.通過參數進行調節,設置map/reduce端的相關參數,如下:

    //每個Map最大輸入大小(這個值決定了合并后文件的數量) set mapred.max.split.size=256000000; //一個節點上split的至少的大小(這個值決定了多個DataNode上的文件是否需要合并) set mapred.min.split.size.per.node=100000000; //一個交換機下split的至少的大小(這個值決定了多個交換機上的文件是否需要合并) set mapred.min.split.size.per.rack=100000000; //執行Map前進行小文件合并 set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; 設置map輸出和reduce輸出進行合并的相關參數: [java] view plain copy //設置map端輸出進行合并,默認為true set hive.merge.mapfiles = true //設置reduce端輸出進行合并,默認為false set hive.merge.mapredfiles = true //設置合并文件的大小 set hive.merge.size.per.task = 256*1000*1000 //當輸出文件的平均大小小于該值時,啟動一個獨立的MapReduce任務進行文件merge。 set hive.merge.smallfiles.avgsize=16000000

    優化點四:sql優化

    1.減少讀取數據量,節約讀取開銷

    1.1 列裁剪

    ??數據量較大的情況下,使用具體的所需字段代替select * 操作。
    ??比如黑科技清單表中有a,b,c,d…z 26列數據,我們需要使用其中的a,b,c三列,使用 "select a,b,c from 黑科技清單"的性能要比"select * from 黑科技清單"好。實際上生產環境一般也會禁止使用select * 操作的。

    1.2 分區裁剪

    對于數據量比較大的表,我們一般會進行分區。業務查詢過程中通過選擇所需分區的方式過濾數據量,也會對查詢性能有明顯的提升。

    1.3 過濾操作

    如果表數據量較大,需要把對業務沒有價值的數據過濾掉再進行關聯等其他查詢操作。

    2. 用group by 語句替代COUNT(DISTINCT)

    1.數據量小的時候COUNT(DISTINCT)性能可能比group by 好,因為group by語句需要子查詢,里外層兩個select 會產生兩個job。
    2.數據量大的情況下,由于COUNT DISTINCT操作需要只用一個Reduce Task來完成,這一個Reduce需要處理的數據量太大,就會導致整個Job很難完成,一般這種情況下,COUNT DISTINCT需要采用先GROUP BY再COUNT的方式替換。

    3.優化in/exists語句

    hive1.2.1后支持了in/exists操作,但還是推薦使用hive的一個高效替代方案:left semi join,例如:

    select a.id, a.name from a where a.id in (select b.id from b); select a.id, a.name from a where exists (select id from b where a.id = b.id);

    應該轉換成:

    select a.id, a.name from a left semi join b on a.id = b.id;

    4. Group by操作

    ??默認情況下,Map階段同一Key數據分發給一個reduce,當一個key數據過大時就傾斜了。進行GROUP BY操作時需要注意以下幾點:
    Map端部分聚合
      事實上并不是所有的聚合操作都需要在reduce部分進行,很多聚合操作都可以先在Map端進行部分聚合,然后reduce端得出最終結果。

    1)開啟Map端聚合參數設置set hive.map.aggr=true2)在Map端進行聚合操作的條數,group的鍵對應的記錄條數超過這個值則會進行分拆,值根據具體數據量設置set hive.grouby.mapaggr.checkinterval=1000003)有數據傾斜的時候進行負載均衡(默認是falseset hive.groupby.skewindata = true

    有數據傾斜時進行負載均衡
      此處需要設定hive.groupby.skewindata,當選項設定為true時,生成的查詢計劃有兩個MapReduce任務。在第一個MapReduce中,map的輸出結果集合會隨機分布到reduce中,每個reduce做部分聚合操作,并輸出結果。這樣處理的結果是,相同的Group By Key有可能分發到不同的reduce中,從而達到負載均衡的目的;第二個MapReduce任務再根據預處理的數據結果按照Group By Key分布到reduce中(這個過程可以保證相同的Group By Key分布到同一個reduce中),最后完成最終的聚合操作。

    5. 利用Hive對UNION ALL優化的特性

    多表union all會優化成一個job
    ??問題:比如推廣效果表要和商品表關聯,效果表中的auction_id列既有32位字符串商品id,也有數字id,和商品表關聯得到商品的信息。
    解決方法:Hive SQL性能會比較好

    SELECT * FROM effect a JOIN(SELECT auction_id AS auction_id FROM auctionsUNION ALLSELECT auction_string_id AS auction_id FROM auctions ) bON a.auction_id=b.auction_id

    比分別過濾數字id,字符串id然后分別和商品表關聯性能要好。商品表只讀一次,推廣效果表只讀取一次。

    6.解決Hive對UNION ALL優化的短板

    Hive對union all的優化的特性:對union all優化只局限于非嵌套查詢

    6.1 消滅子查詢內的group by

    SELECT * FROM(SELECT * FROM t1 GROUP BY c1,c2,c3UNION ALLSELECT * FROM t2 GROUP BY c1,c2,c3 ) t3 GROUP BY c1,c2,c3

    ??從業務邏輯上說,子查詢內的GROUP BY怎么看都是多余(功能上的多余,除非有COUNT(DISTINCT)),如果不是因為Hive Bug或者性能上的考量(曾經出現如果不執行子查詢GROUP BY,數據得不到正確的結果的Hive Bug)。所以這個Hive按經驗轉換成如下所示:

    SELECT * FROM (SELECT * FROM t1 UNION ALL SELECT * FROM t2) t3 GROUP BY c1,c2,c3

    ??經過測試,并未出現union all的Hive Bug,數據是一致的。MapReduce的作業數由3減少到1。
    t1相當于一個目錄,t2相當于一個目錄,對Map/Reduce程序來說,t1、t2可以作為Map/Reduce作業的mutli inputs。這可以通過一個Map/Reduce來解決這個問題。Hadoop的計算框架,不怕數據多,就怕作業數多。
    但如果換成是其他計算平臺如Oracle,那就不一定了,因為把大輸入拆成兩個輸入,分別排序匯總成merge(假如兩個子排序是并行的話),是有可能性能更優的(比如希爾排序比冒泡排序的性能更優)。

    6.2 消滅子查詢內的COUNT(DISTINCT),MAX,MIN

    6.3 消滅子查詢內的JOIN

    SELECT * FROM(SELECT * FROM t1UNION ALLSELECT * FROM t4UNION ALLSELECT * FROM t2 JOIN t3ON t2.id=t3.id ) x GROUP BY c1,c2; -- 上面代碼運行會有5個jobs。加入先JOIN生存臨時表的話t5,然后UNION ALL,會變成2個jobs。 INSERT OVERWRITE TABLE t5 SELECT * FROM t2 JOIN t3 ON t2.id=t3.id; SELECT * FROM (t1 UNION ALL t4 UNION ALL t5); -- 調優結果顯示:針對千萬級別的廣告位表,由原先5個Job共15分鐘,分解為2個job,一個8-10分鐘,一個3分鐘。

    7. JOIN操作

    7.1 小表、大表JOIN(新版本已經優化,紀念一下青春吧)

    ??在使用寫有Join操作的查詢語句時有一條原則:應該將條目少的表/子查詢放在Join操作符的左邊。原因是在Join操作的Reduce階段,位于Join操作符左邊的表的內容會被加載進內存,將條目少的表放在左邊,可以有效減少發生OOM錯誤的幾率;再進一步,可以使用Group讓小的維度表(1000條以下的記錄條數)先進內存。在map端完成reduce。
      實際測試發現:新版的hive已經對小表JOIN大表和大表JOIN小表進行了優化。小表放在左邊和右邊已經沒有明顯區別。

    優化點五:使用向量化查詢

    ??向量化查詢執行通過一次性批量執行1024行而不是每次單行執行,從而提供掃描、聚合、篩選器和連接等操作的性能。在Hive 0.13中引入,此功能顯著提高了查詢執行時間,并可通過兩個參數設置輕松啟用:

      設置hive.vectorized.execution.enabled = true;設置hive.vectorized.execution.reduce.enabled = true;

    向量化查詢只支持orc等列存儲格式。

    優化點六:選擇引擎

    ??Hive可以使用Apache Tez執行引擎而不是古老的Map-Reduce引擎。在環境中沒有默認打開,在Hive查詢開頭將以下內容設置為‘true’來使用Tez:

    使用Tez 引擎: set hive.execution.engine = tez; 使用spark 引擎: set hive.execution.engine = spark;

    優化點七:存儲格式

    存儲格式存儲方式特點
    TextFile行存儲存儲空間消耗比較大,并且壓縮的text 無法分割和合并 查詢的效率最低,可以直接存儲,加載數據的速度最高
    SequenceFile行存儲存儲空間消耗最大,壓縮的文件可以分割和合并 查詢效率高,需要通過text文件轉化來加載
    RCFile數據按行分塊
    每塊按列存儲
    存儲空間最小,
    查詢的效率最高 ,
    需要通過text文件轉化來加載,
    加載的速度最低。
    壓縮快 快速列存取。
    讀記錄盡量涉及到的block最少
    讀取需要的列只需要讀取每個row group 的頭部定義。
    讀取全量數據的操作 性能可能比sequencefile沒有明顯的優勢
    ORCFile數據按行分塊
    每塊按列存儲
    壓縮快,快速列存取 ,效率比rcfile高,是rcfile的改良版本
    Parquet列存儲相對于PRC,Parquet壓縮比較低,查詢效率較低,不支持update、insert和ACID.但是Parquet支持Impala查詢引擎
    推薦使用orcFile;

    優化點八:壓縮格式

    ??大數據場景下存儲格式壓縮格式尤為關鍵,可以提升計算速度,減少存儲空間,降低網絡io,磁盤io,所以要選擇合適的壓縮格式和存儲格式。
    ??壓縮比率,壓縮解壓縮速度,是否支持Split,這三點是選擇壓縮格式要考慮的要素。

    優化點九:運行模式選擇

    1.本地模式

    ??對于大多數情況,Hive可以通過本地模式在單臺機器上處理所有任務。對于小數據,執行時間可以明顯被縮短。開啟本地模式,簡單查詢將不會提交到yarn。

    set hive.exec.mode.local.auto=true; -- 開啟本地mr -- 設置local mr的最大輸入數據量,當輸入數據量小于這個值時采用local mr的方式,默認為134217728,即128M set hive.exec.mode.local.auto.inputbytes.max=50000000; -- 設置local mr的最大輸入文件個數,當輸入文件個數小于這個值時采用local mr的方式,默認為4 set hive.exec.mode.local.auto.input.files.max=10;

    2.并行模式

    ??Hive會將一個查詢轉化成一個或多個階段。這樣的階段可以是MapReduce階段、抽樣階段、合并階段、limit階段。默認情況下,Hive一次只會執行一個階段,由于job包含多個階段,而這些階段并非完全相互依賴,即:這些階段可以并行執行,可以縮短整個job的執行時間。設置參數,set hive.exec.parallel=true,或者通過配置文件來完成:

    3.嚴格模式

    Hive提供一個嚴格模式,可以防止用戶執行那些可能產生意想不到的影響查詢,通過設置Hive.mapred.modestrict來完成。
    set hive.mapred.mode=strict;

    3.1 設置為嚴格模式后,可以禁止3種類型的查詢:

    a.不帶分區或過濾的分區表查詢

    ??如果在一個分區表執行查詢,除非where語句中包含分區字段過濾條件來顯示數據范圍,否則不允許執行。換句話說就是在嚴格模式下不允許用戶掃描所有的分區。

    b. 帶有order by的查詢

    對于使用了orderby的查詢,要求必須有limit語句。因為orderby為了執行排序過程會將所有的結果分發到同一個reducer中
    進行處理,強烈要求用戶增加這個limit語句可以防止reducer額外執行很長一段時間。

    c. 限制笛卡爾積的查詢

    嚴格模式下,進行笛卡爾積的查詢會報錯,必須要有on條件。

    優化點十:JVM重用

    ??JVM重用是Hadoop調優參數的內容,其對Hive的性能具有非常大的影響,特別是對于很難避免小文件的場景或task特別多的場景,這類場景大多數task執行時間都很短。
    ?? Hadoop的默認配置通常是使用派生JVM來執行map和Reduce任務的。這時JVM的啟動過程可能會造成相當大的開銷,尤其是執行的job包含有成百上千task任務的情況。JVM重用可以使得JVM實例在同一個job中重新使用N次。N的值可以在Hadoop的mapred-site.xml文件中進行配置。通常在10-20之間,具體多少需要根據具體業務場景測試得出。

    <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>

    ??我們也可以在hive當中通過

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

    ??這個設置來設置我們的jvm重用。
    ??當然,這個功能也是有它的缺點的。開啟JVM重用將一直占用使用到的task插槽,以便進行重用,直到任務完成后才能釋放。如果某個“不平衡的”job中有某幾個reduce task執行的時間要比其他Reduce task消耗的時間多的多的話,那么保留的插槽就會一直空閑著卻無法被其他的job使用,直到所有的task都結束了才會釋放。

    優化點十一:推測執行

    ??在分布式集群環境下,因為程序Bug(包括Hadoop本身的bug),負載不均衡或者資源分布不均等原因,會造成同一個作業的多個任務之間運行速度不一致,有些任務的運行速度可能明顯慢于其他任務(比如一個作業的某個任務進度只有50%,而其他所有任務已經運行完畢),則這些任務會拖慢作業的整體執行進度。為了避免這種情況發生,Hadoop采用了推測執行(Speculative Execution)機制,它根據一定的法則推測出“拖后腿”的任務,并為這樣的任務啟動一個備份任務,讓該任務與原始任務同時處理同一份數據,并最終選用最先成功運行完成任務的計算結果作為最終結果。

    mapred.map.tasks.speculative.execution=true mapred.reduce.tasks.speculative.execution=true

    ??關于調優這些推測執行變量,還很難給一個具體的建議。如果用戶對于運行時的偏差非常敏感的話,那么可以將這些功能關閉掉。如果用戶因為輸入數據量很大而需要執行長時間的map或者Reduce task的話,那么啟動推測執行造成的浪費是非常巨大大。數據量過于龐大,備份task有可能直接打垮集群。

    優化點十二:分區、分桶表

    ??1.對于一張比較大的表,將其設計成分區表,避免全表掃描。
    ??2.當很難在列上創建分區時,我們會使用分桶,比如某個經常被篩選的字段,如果將其作為分區字段,會造成大量的分區。在Hive中,會對分桶字段進行哈希,從而提供了中額外的數據結構,進行提升查詢效率。
    ??與分區表類似,分桶表的組織方式是將HDFS上的文件分割成多個文件。分桶可以加快數據采樣,也可以提升join的性能(join的字段是分桶字段),因為分桶可以確保某個key對應的數據在一個特定的桶內(文件),所以巧妙地選擇分桶字段可以大幅度提升join的性能。通常情況下,分桶字段可以選擇經常用在過濾操作或者join操作的字段。
    ??我們可以使用set.hive.enforce.bucketing = true啟用分桶設置。
    ??當使用分桶表時,最好將bucketmapjoin標志設置為true,具體配置參數為:

    SET hive.optimize.bucketmapjoin = true

    優化點十三:對中間數據啟用壓縮

    ??復雜的Hive查詢通常會轉換為一系列多階段的MapReduce作業,并且這些作業將由Hive引擎連接起來以完成整個查詢。因此,此處的“中間輸出”是指上一個MapReduce作業的輸出,它將用作下一個MapReduce作業的輸入數據。
    ??壓縮可以顯著減少中間數據量,從而在內部減少了Map和Reduce之間的數據傳輸量。
    ??我們可以使用以下屬性在中間輸出上啟用壓縮。

    set hive.exec.compress.intermediate=true;set hive.intermediate.compression.codec=org.apache.hadoop.io.compress.SnappyCodec;set hive.intermediate.compression.type=BLOCK;

    為了將最終輸出到HDFS的數據進行壓縮,可以使用以下屬性:

    set hive.exec.compress.output=true;

    優化點十四:謂詞下推

    比如下面的查詢:

    select a.*,b.* from a join b on a.col1 = b.col1 where a.col1 > 15 and b.col2 > 16

    ??如果沒有謂詞下推,則在完成JOIN處理之后將執行過濾條件(a.col1> 15 and b.col2> 16)。因此,在這種情況下,JOIN將首先發生,并且可能產生更多的行,然后在進行過濾操作。
    ??使用謂詞下推,這兩個謂詞**(a.col1> 15和b.col2> 16)**將在JOIN之前被處理,因此它可能會從a和b中過濾掉連接中較早處理的大部分數據行,因此,建議啟用謂詞下推。
    通過將hive.optimize.ppd設置為true可以啟用謂詞下推。

    SET hive.optimize.ppd=true

    ??如果使用外連接,則謂詞下推會失效

    select a.id,a.c1,b.c2 from a left join b on a.id=b.id where b.dt >= '20181201' and b.dt <'20190101'

    優化點十五:基于成本的優化

    ??Hive在提交最終執行之前會優化每個查詢的邏輯和物理執行計劃。基于成本的優化會根據查詢成本進行進一步的優化,從而可能產生不同的決策:比如如何決定JOIN的順序,執行哪種類型的JOIN以及并行度等。
    ??可以通過設置以下參數來啟用基于成本的優化。

    set hive.cbo.enable=true; set hive.compute.query.using.stats=true; set hive.stats.fetch.column.stats=true; set hive.stats.fetch.partition.stats=true;

    ??可以使用統計信息來優化查詢以提高性能。基于成本的優化器(CBO)還使用統計信息來比較查詢計劃并選擇最佳計劃。通過查看統計信息而不是運行查詢,效率會很高。
    ??收集表的列統計信息:

    ANALYZE TABLE table_name COMPUTE STATISTICS FOR COLUMNS;

    ??查看my_db數據庫中my_table中my_id列的列統計信息:

    DESCRIBE FORMATTED my_db.my_table my_id

    優化點十六:insert into操作

    1.插入數據量較大

    ??如果插入過程中有多個union all(union all個數大于2),或者插入的數據量比較大,應該拆成多個insert into 語句并行執行,實際測試過程中,執行時間能提升50%。

    2.多次掃描表

    INSERT INTO temp_table_20201115 SELECT * FROM my_table WHERE dt ='2020-11-15'; INSERT INTO temp_table_20201116 SELECT * FROM my_table WHERE dt ='2020-11-16';

    如上面的邏輯,將一張表多次查詢寫入多張表中,多次讀表會消耗很多性能,我們可以優化為讀一次表寫入多個表:

    FROM my_tableINSERT INSERT INTO temp_table_20201115 SELECT * WHERE dt ='2020-11-15' INSERT INTO temp_table_20201116 SELECT * WHERE dt ='2020-11-16'

    優化點十七:好的模型設計

    優化點十八:良好的sql開發能力

    參考文獻:

    https://www.cnblogs.com/swordfall/p/11037539.html
    https://blog.csdn.net/weixin_44318830/article/details/103336579
    https://baijiahao.baidu.com/s?id=1721265748021502455&wfr=spider&for=pc
    https://www.cnblogs.com/liuxinrong/articles/12695181.html
    https://www.cnblogs.com/junstudys/p/10056830.html

    總結

    以上是生活随笔為你收集整理的HIVE 优化浅谈的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。