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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

Hive优化语句

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

hive建表設計層面

1.使用分區表優化

分區表 是在某一個或者幾個維度上對數據進行分類存儲,一個分區對應一個目錄。如果篩選條件里有分
區字段,那么 Hive 只需要遍歷對應分區目錄下的文件即可,不需要遍歷全局數據,使得處理的數據量
大大減少,從而提高查詢效率。

也就是說:當一個 Hive 表的查詢大多數情況下,會根據某一個字段進行篩選時,那么非常適合創建為
分區表,該字段即為分區字段。

2.使用分桶表優化

跟分區的概念很相似,都是把數據分成多個不同的類別,區別就是規則不一樣!

1、分區:按照字段值來進行:一個分區,就只是包含這個這一個值的所有記錄
不是當前分區的數據一定不在當前分區
當前分區也只會包含當前這個分區值的數據

2、分桶:默認規則:Hash散列
一個分桶中會有多個不同的值
如果一個分桶中,包含了某個值,這個值的所有記錄,必然都在這個分桶

Hive Bucket,分桶,是指將數據以指定列的值為 key 進行 hash,hash 到指定數目的桶中,這樣做的
目的和分區表類似,使得篩選時不用全局遍歷所有的數據,只需要遍歷所在桶就可以了。這樣也可以支
持高效采樣。

3.選擇合適的文件存儲格式

Apache Hive支持 Apache Hadoop 中使用的幾種熟悉的文件格式,比如 TextFile、SequenceFile、RCFile、Avro、ORC、ParquetFile等。

存儲格式一般需要根據業務進行選擇,在我們的實操中,絕大多數表都采用TextFile與Parquet兩種存儲
格式之一。 TextFile是最簡單的存儲格式,它是純文本記錄,也是Hive的默認格式。雖然它的磁盤開銷
比較大,查詢效率也低,但它更多地是作為跳板來使用。RCFile、ORC、Parquet等格式的表都不能由
文件直接導入數據,必須由TextFile來做中轉。 Parquet和ORC都是Apache旗下的開源列式存儲格式。
列式存儲比起傳統的行式存儲更適合批量OLAP查詢,并且也支持更好的壓縮和編碼。

創建表時,特別是寬表,盡量使用 ORC、ParquetFile 這些列式存儲格式,因為列式存儲的表,每一
列的數據在物理上是存儲在一起的,Hive查詢時會只遍歷需要列數據,大大減少處理的數據量。

第一種:TextFile

1、存儲方式:行存儲。默認格式,如果建表時不指定默認為此格式。,
2、每一行都是一條記錄,每行都以換行符"\n"結尾。數據不做壓縮時,磁盤會開銷比較大,數據解析開銷也 比較大。
3、可結合Gzip、Bzip2等壓縮方式一起使用(系統會自動檢查,查詢時會自動解壓),推薦選用可切分的壓 縮算法。

第二種:Sequence File

1、一種Hadoop API提供的二進制文件,使用方便、可分割、個壓縮的特點。
2、支持三種壓縮選擇:NONE、RECORD、BLOCK。RECORD壓縮率低,一般建議使用BLOCK壓縮。

第三種:RC File

1、存儲方式:數據按行分塊,每塊按照列存儲 。
A、首先,將數據按行分塊,保證同一個record在一個塊上,避免讀一個記錄需要讀取多個block。
B、其次,塊數據列式存儲,有利于數據壓縮和快速的列存取。
2、相對來說,RCFile對于提升任務執行性能提升不大,但是能節省一些存儲空間。可以使用升級版的ORC格 式。

第四種:ORC File

1、存儲方式:數據按行分塊,每塊按照列存儲
2、Hive提供的新格式,屬于RCFile的升級版,性能有大幅度提升,而且數據可以壓縮存儲,壓縮快,快速 列存取。 3、ORC
File會基于列創建索引,當查詢的時候會很快。

第五種:Parquet File

1、存儲方式:列式存儲。
2、Parquet對于大型查詢的類型是高效的。對于掃描特定表格中的特定列查詢,Parquet特別有用。
Parquet一般使用Snappy、Gzip壓縮。默認Snappy。
3、Parquet支持Impala 查詢引擎。
4、表的文件存儲格式盡量采用Parquet或ORC,不僅降低存儲量,還優化了查詢,壓縮,表關聯等性能。

4.選擇合適的壓縮格式

Hive 語句最終是轉化為 MapReduce 程序來執行的,而 MapReduce 的性能瓶頸在與 網絡IO 和 磁盤
IO,要解決性能瓶頸,最主要的是 減少數據量,對數據進行壓縮是個好方式。壓縮雖然是減少了數據
量,但是壓縮過程要消耗 CPU,但是在 Hadoop 中,往往性能瓶頸不在于 CPU,CPU 壓力并不大,所
以壓縮充分利用了比較空閑的 CPU。

map階段輸出數據壓縮 ,在這個階段,優先選擇一個低CPU開銷的算法。

set hive.exec.compress.intermediate=true set mapred.map.output.compression.codec= org.apache.hadoop.io.compress.SnappyCodec set mapred.map.output.compression.codec=com.hadoop.compression.lzo.LzoCodec;

對最終輸出結果壓縮

set hive.exec.compress.output=true set mapred.output.compression.codec=org.apache.hadoop.io.compress.SnappyCodec

##當然,也可以在hive建表時指定表的文件格式和壓縮編碼
結論,一般選擇orcfile/parquet + snappy 方式

sql語法和運行參數層面

1.列裁剪

列裁剪就是在查詢時只讀取需要的列,分區裁剪就是只讀取需要的分區。當列很多或者數據量很大時,
如果 select * 或者不指定分區,全列掃描和全表掃描效率都很低。
Hive 在讀數據的時候,可以只讀取查詢中所需要用到的列,而忽略其他的列。這樣做可以節省讀取開
銷:中間表存儲開銷和數據整合開銷。

set hive.optimize.cp = true; ## 列裁剪,取數只取查詢中需要用到的列,默認是true

2.謂詞下推

將 SQL 語句中的 where 謂詞邏輯都盡可能提前執行,減少下游處理的數據量。對應邏輯優化器是
PredicatePushDown。

set hive.optimize.ppd=true;

3.合并小文件

在執行 MapReduce 程序的時候,一般情況是一個文件的一個數據分塊需要一個 mapTask 來處理。但
是如果數據源是大量的小文件,這樣就會啟動大量的 mapTask 任務,這樣會浪費大量資源。可以將輸
入的小文件進行合并,從而減少 mapTask 任務數量。

4.合理控制map task和reduce task的數量

這個優化措施,但凡能用就用! 大表 join 小表 小表滿足需求: 小表數據小于控制條件時
MapJoin 是將 join 雙方比較小的表直接分發到各個 map 進程的內存中,在 map 進程中進行 join 操
作,這樣就不用進行 reduce 步驟,從而提高了速度。只有 join 操作才能啟用 MapJoin。

5.join 數據傾斜優化

在編寫 Join 查詢語句時,如果確定是由于 join 出現的數據傾斜,那么請做如下設置:

join的鍵對應的記錄條數超過這個值則會進行分拆,值根據具體數據量設置

set hive.skewjoin.key=100000;

如果是join過程出現傾斜應該設置為true

set hive.optimize.skewjoin=false;

如果開啟了,在 Join 過程中 Hive 會將計數超過閾值 hive.skewjoin.key(默認100000)的傾斜 key 對
應的行臨時寫進文件中,然后再啟動另一個 job 做 map join 生成結果。
通過 hive.skewjoin.mapjoin.map.tasks 參數還可以控制第二個 job 的 mapper 數量,默認
10000。

6.CBO優化

join的時候表的順序的關系:前面的表都會被加載到內存中。后面的表進行磁盤掃描。

select a.*, b.*, c.* from a join b on a.id = b.id join c on a.id = c.id;

Hive 自 0.14.0 開始,加入了一項 “Cost based Optimizer” 來對 HQL 執行計劃進行優化,這個功能通
過 “hive.cbo.enable” 來開啟。在 Hive 1.1.0 之后,這個 feature 是默認開啟的,它可以 自動優化 HQL
中多個 Join 的順序,并選擇合適的 Join 算法。

CBO,成本優化器,代價最小的執行計劃就是最好的執行計劃。傳統的數據庫,成本優化器做出最優化
的執行計劃是依據統計信息來計算的。Hive 的成本優化器也一樣。
Hive 在提供最終執行前,優化每個查詢的執行邏輯和物理執行計劃。這些優化工作是交給底層來完成
的。根據查詢成本執行進一步的優化,從而產生潛在的不同決策:如何排序連接,執行哪種類型的連
接,并行度等等。
要使用基于成本的優化(也稱為CBO),請在查詢開始設置以下參數:

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;

hive架構層面

1.啟用本地抓取

Hive 的某些 SQL 語句需要轉換成 MapReduce 的操作,某些 SQL 語句就不需要轉換成 MapReduce 操
作,但是同學們需要注意,理論上來說,所有的 SQL 語句都需要轉換成 MapReduce 操作,只不過
Hive 在轉換 SQL 語句的過程中會做部分優化,使某些簡單的操作不再需要轉換成 MapReduce,例
如:

1、只是 select * 的時候
2、where 條件針對分區字段進行篩選過濾時
3、帶有 limit 分支語句時

Hive 從 HDFS 中讀取數據,有兩種方式:啟用MapReduce讀取 和 直接抓取。
直接抓取數據比 MapReduce 方式讀取數據要快的多,但是只有少數操作可以使用直接抓取方式。
可以通過 hive.fetch.task.conversion 參數來配置在什么情況下采用直接抓取方式:

minimal:只有 select * 、在分區字段上 where 過濾、有 limit 這三種場景下才啟用直接抓取方式。 more:在
select、where 篩選、limit 時,都啟用直接抓取方式。

2.本地執行優化

Hive 在集群上查詢時,默認是在集群上多臺機器上運行,需要多個機器進行協調運行,這種方式很好
的解決了大數據量的查詢問題。但是在 Hive 查詢處理的數據量比較小的時候,其實沒有必要啟動分布
式模式去執行,因為以分布式方式執行設計到跨網絡傳輸、多節點協調等,并且消耗資源。對于小數據
集,可以通過本地模式,在單臺機器上處理所有任務,執行時間明顯被縮短。

啟動本地模式涉及到三個參數:

--打開hive自動判斷是否啟動本地模式的開關 set hive.exec.mode.local.auto=true; -- map任務數最大值,不啟用本地模式的task最大個數 set hive.exec.mode.local.auto.input.files.max=4; -- map輸入文件最大大小,不啟動本地模式的最大輸入文件大小 set hive.exec.mode.local.auto.inputbytes.max=134217728;

3.JVM重用

Hive 語句最終會轉換為一系列的 MapReduce 任務,每一個MapReduce 任務是由一系列的 MapTask
和 ReduceTask 組成的,默認情況下,MapReduce 中一個 MapTask 或者 ReduceTask 就會啟動一個
JVM 進程,一個 Task 執行完畢后,JVM 進程就會退出。這樣如果任務花費時間很短,又要多次啟動
JVM 的情況下,JVM 的啟動時間會變成一個比較大的消耗,這時,可以通過重用 JVM 來解決。

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

JVM也是有缺點的,開啟JVM重用會一直占用使用到的 task 的插槽,以便進行重用,直到任務完成后才
會釋放。如果某個 不平衡的job 中有幾個 reduce task 執行的時間要比其他的 reduce task 消耗的時間
要多得多的話,那么保留的插槽就會一直空閑卻無法被其他的 job 使用,直到所有的 task 都結束了才
會釋放。
根據經驗,一般來說可以使用一個 cpu core 啟動一個 JVM,假如服務器有 16 個 cpu core ,但是這個
節點,可能會啟動 32 個mapTask,完全可以考慮:啟動一個JVM,執行兩個Task。

4.并行執行

有的查詢語句,Hive 會將其轉化為一個或多個階段,包括:MapReduce 階段、抽樣階段、合并階段、
limit 階段等。默認情況下,一次只執行一個階段。但是,如果某些階段不是互相依賴,是可以并行執行
的。多階段并行是比較耗系統資源的。
一個 Hive SQL 語句可能會轉為多個 MapReduce Job,每一個 job 就是一個 stage,這些 Job 順序執
行,這個在 cli 的運行日志中也可以看到。但是有時候這些任務之間并不是是相互依賴的,如果集群資
源允許的話,可以讓多個并不相互依賴 stage 并發執行,這樣就節約了時間,提高了執行速度,但是如
果集群資源匱乏時,啟用并行化反倒是會導致各個 Job 相互搶占資源而導致整體執行性能的下降。啟用
并行化:

-- 可以開啟并發執行。 set hive.exec.parallel=true; --同一個sql允許最大并行度,默認為8。 set hive.exec.parallel.thread.number=16;

sql優化

1 對于這個調優,有待再次驗證目前我驗證了4千萬 join 8千萬發現不管是left join還是inner join,執行計劃差不多,job數,maptask,reducetask數都一樣,執行時長也差不多可能都已經自動優化了(謂詞下推)

select count(1) from test1 t1 inner join test2 t2 on t1.uuid = t2.uuid and t2.date_id =2020-10-23where t1.date_id =2020-10-23’;select count(1) from (select * from test1 where date_id =2020-10-23) t1 inner join test2 t2 on t1.uuid = t2.uuid and t2.date_id =2020-10-23

;

2 .union優化

盡量不要使用union (union 去掉重復的記錄)而是使用 union all 然后再用group by 去重

3 .count distinct優化

數據量小的時候無所謂,數據量大的情況下,由于COUNT DISTINCT操作需要用一個Reduce Task來完成,這一個Reduce需要處理的數據量太大,就會導致整個Job很難完成,一般COUNT DISTINCT使用先GROUP BY再COUNT的方式替換:
不要使用count (distinct cloumn) ,使用子查詢

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

雖然會多用一個Job來完成,但在數據量大的情況下,這個絕對是值得的。

4.用in 來代替join

如果需要根據一個表的字段來約束另為一個表,盡量用in來代替join . in 要比join 快

select a.Id ,name from tb1 a join tb2 b on(a.id = b.id); select Id ,name from tb1 where id in(select id from tb2);

5. Left semi join優化in/exists

(a表和b表通過user_id關聯)
a表數據

select * from wedw_dw.t_user;


b表數據

select * from wedw_dw.t_order;


l

--left semi join Select * from wedw_dw.t_user t1 left semi join wedw_dw.t_order t2 on t1.user_id = t2.user_id;

如圖所示:只能展示a表的字段,因為left semi join 只傳遞表的 join key 給 map 階段

總結

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

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