當前位置:首頁 » 編程語言 » sql優化hive
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

sql優化hive

發布時間: 2023-07-18 23:42:42

1. hive sql 優化的常用手段有哪些

1、join連接時的優化:當三個或多個以上的表進行join操作時,如果每個on使用相同的欄位連接時只會產生一個maprece。
2、join連接時的優化:當多個表進行查詢時,從左到右表的大小順序應該是從小到大。原因:hive在對每行記錄操作時會把其他表先緩存起來,直到掃描最後的表進行計算
3、在where字句中增加分區過濾器。
4、當可以使用left semi join 語法時不要使用inner join,前者效率更高。原因:對於左表中指定的一條記錄,一旦在右表中找到立即停止掃描。

2. 數據分析課程筆記 - 19 - HiveSQL 常用優化技巧

大家好呀,這節課學習 HiveSQL 的常用優化技巧。由於 Hive 主要用來處理非常大的數據,運行過程由於通常要經過 MapRece 的過程,因此不像 MySQL 一樣很快出結果。而使用不同方法寫出來的 HiveSQL 語句執行效率也是不一樣的,因此為了減少等待的時間,提高伺服器的運行效率,我們需要在 HiveSQL 的語句上進行一些優化。

本節課的主要內容

引言
1、技巧一:列裁剪和分區裁剪
(1)列裁剪
(2)分區裁剪
2、技巧二:排序技巧——sort by代替order by
3、技巧三:去重技巧——用group by來替換distinct
4、技巧四:聚合技巧——grouping sets、cube、rollup
(1)grouping sets
(2)cube
(3)rollup
5、技巧五:換個思路解題
6、技巧六:union all時可以開啟並發執行
7、技巧七:表連接優化
8、技巧八:遵循嚴格模式

Hive 作為大數據領域常用的數據倉庫組件,在平時設計和查詢時要特別注意效率。影響Hive效率的幾乎從不是數據量過大,而是數據傾斜、數據冗餘、job 或 I/O 過多、MapRece 分配不合理等等。對 Hive 的調優既包含對HiveSQL 語句本身的優化,也包含 Hive 配置項和 MR 方面的調整。

列裁剪就是在查詢時只讀取需要的列。當列很多或者數據量很大時,如果select 所有的列或者不指定分區,導致的全表掃描和全分區掃描效率都很低。Hive中與列裁剪優化相關的配置項是 hive.optimize.cp ,默認是 true 。

分區裁剪就是在查詢時只讀需要的分區。Hive中與分區裁剪優化相關的則是 hive.optimize.pruner ,默認是 true 。

HiveSQL中的 order by 與其他 SQL 語言中的功能一樣,就是將結果按某個欄位全局排序,這會導致所有map端數據都進入一個 rece 中,在數據量大時可能會長時間計算不完。

如果使用 sort by ,那麼就會視情況啟動多個 recer 進行排序,並且保證每個 recer 內局部有序。為了控制 map 端數據分配到 rece 的 key,往往還要配合 distribute by 一同使用。如果不加 distribute by 的話,map 端數據就會隨機分配給 recer。

這里需要解釋一下, distribute by 和 sort by 結合使用是如何相較於 order by 提升運行效率的。

假如我們要對一張很大的用戶信息表按照年齡進行分組,優化前的寫法是直接 order by age 。使用 distribute by 和 sort by 結合進行優化的時候, sort by 後面還是 age 這個排序欄位, distribute by 後面選擇一個沒有重復值的均勻欄位,比如 user_id 。

這樣做的原因是,通常用戶的年齡分布是不均勻的,比如20歲以下和50歲以上的人非常少,中間幾個年齡段的人又非常多,在 Map 階段就會造成有些任務很大,有些任務很小。那通過 distribute by 一個均勻欄位,就可以讓系統均勻地進行「分桶」,對每個桶進行排序,最後再組合,這樣就能從整體上提升 MapRece 的效率。

取出 user_trade 表中全部支付用戶:

原有寫法的執行時長:

優化寫法的執行時長:

考慮對之前的案例進行優化:

注意: 在極大的數據量(且很多重復值)時,可以先 group by 去重,再 count() 計數,效率高於直接 count(distinct **) 。

如果我們想知道用戶的性別分布、城市分布、等級分布,你會怎麼寫?

通常寫法:

缺點 :要分別寫三次SQL,需要執行三次,重復工作,且費時。

那該怎麼優化呢?

注意 :這個聚合結果相當於縱向地堆在一起了(Union all),分類欄位用不同列來進行區分,也就是每一行數據都包含 4 列,前三列是分類欄位,最後一列是聚合計算的結果。

GROUPING SETS() :在 group by 查詢中,根據不同的維度組合進行聚合,等價於將不同維度的 group by 結果集進行 union all。聚合規則在括弧中進行指定。

如果我們想知道用戶的性別分布以及每個性別的城市分布,你會怎麼寫?

那該怎麼優化呢?

注意: 第二列為NULL的,就是性別的用戶分布,其餘有城市的均為每個性別的城市分布。

cube:根據 group by 維度的所有組合進行聚合

注意 :跑完數據後,整理很關鍵!!!

rollup:以最左側的維度為主,進行層級聚合,是cube的子集。

如果我想同時計算出,每個月的支付金額,以及每年的總支付金額,該怎麼辦?

那應該如何優化呢?

條條大路通羅馬,寫SQL亦是如此,能達到同樣效果的SQL有很多種,要學會思路轉換,靈活應用。

來看一個我們之前做過的案例:

有沒有別的寫法呢?

Hive 中互相沒有依賴關系的 job 間是可以並行執行的,最典型的就是
多個子查詢union all。在集群資源相對充足的情況下,可以開啟並
行執行。參數設置: set hive.exec.parallel=true;

時間對比:

所謂嚴格模式,就是強制不允許用戶執行3種有風險的 HiveSQL 語句,一旦執行會直接報錯。

要開啟嚴格模式,需要將參數 hive.mapred.mode 設為 strict 。

好啦,這節課的內容就是這些。以上優化技巧需要大家在平時的練習和使用中有意識地去注意自己的語句,不斷改進,就能掌握最優的寫法。

3. hive優化方法

1、列裁剪和分區裁剪

2、謂詞下推

3、sort by 替換order by 

4、group by 代替distinct

5、group by 配置調整

map 端預聚合:set hive.map.aggr=true ; set hive.groupby.mapaggr.checkinterval=100000

傾斜均衡配置項:set hive.groupby.skewindate=true

6、join優化

6.1 大小表,小表前置

6.2 多表Join時key相同

6.3 利用mapjoin特性

6.4 分桶表 mapjoin

6.5 傾斜均衡配置項:

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

6.7 優化sql處理join數據傾斜

6.7.1、空值或無意義的值:若不需要空值數據,就提前寫到where語句過濾掉,如果需要保留的話,將空值key用隨機方式打散。

6.7.2、單獨處理傾斜key

6.7.3、不同數據類型,join的關聯欄位類型不一樣,導致耗時長,所以需要注意做類型轉換(join關聯欄位,一個是int,一個是string,,計算key的hash值時默認時int類型做的,這樣導致所有真正的string類型的key都分配到一個recer上了)

6.7.4、mapjoin的小表比較大的時候,,無法直接使用mapjoin,則 select/*+mapjoin(b)*/  from  a left join ( select /*+mapjoin (b)*/ from b inner join a )

6.8、maprece 優化

6.8.1、調整mapper數

mapper數量與輸入文件的split數息息相關。如果想減少mapper數,就適當提高mapred.min.split.size,split數就減少了;如果想增大mapper數,除了降低maperd.min.split.size之外,也可以提高mapred.map.task;一般來講,如果輸入文件是少量大文件,就減少mapper數;如果是大量非小文件,就增大mapper數,如果是小文件,就喝吧小文件

6.8.2 調整recer數

使用參數mapred.rece.task可以直接設定recer數量,如果不設置的話,hive會自行推測,推測邏輯如下:

參數hive.exec.recers.bytes.per.recer.設定每個recer能夠處理的最大的數據量,默認時1G

參數hive.exec.recers.max設定每個job的最大的recer數量,默認時999或者1009

得到recer數:recers_num=min(total_input_size/recers.bytes.per.recer,recers.max)

recer數量與輸出文件的數量相關,如果recer數太多,會產生大量小文件,對hdfs造成壓力,如果recer數太少,每個recer要處理很多數據,容易拖慢運行時間或造成oom

6.8.3 合並小文件

輸入階段合並:需要更改hive的輸入文件格式,即參數hive.input.format,默認值是org.apache.hadoop.hive.ql.io.hiveiputformat,我們該成org.apache.hadoop.hive.ql.io.combinehiveinputformat.

這樣比調整mapper數時,又多出兩個參數,分別是mapred.min.split.size.per.node和mapred.min.split.size.per.rack,含義是單節點和單機架上的最小split大小。如果發現又split大小小於這兩個默認值100MB,則會進行合並

輸出階段合並:直接將hive.merge.mapfiles和hive.merge.mapredfiles都設置為true即可。

hive.merge.mapfiles表示將map-only任務的輸出合並

hive.merge.mapredfiles表示將map-rece任務的輸出合並

另外hive.merge.size.per.task可以指定每個task輸出後合並文件大小的期望值

hive.merge.size.smallfiles.avgsize可以指定所有輸出文件大小的均值閾值,默認時1G

6.9 啟用壓縮

壓縮job的中間結果數據和輸出數據,可以少量CPU時間節省出很多空間。壓縮方式一般選擇snappy,效率最高,要啟用中間壓縮,需要設定:

hive.exec.compress.intermediate為true,同時指定壓縮方式hive.intermediate.compression.code為org.apache.hadoop.io.compress.snappycode.

另外,參數hive.intermediate.compression.type可以選對塊block還是對記錄record壓縮,block壓縮率比較高,輸出壓縮的配置基本相同:打開hive.exec.compress.output

6.10 jvm重用

在mr job中,默認時每執行一個task就會啟動一個jvm,如果task非常小而且碎,那麼jvm啟動和關閉耗時都會比較長。可以通過調節參數mapred.job.reuse.jvm.num.task來重用。例如將這個參數設置為5,那麼久代表同一個mr job中順序執行的5各task可以重復使用一個jvm,減少啟動和關閉開銷,但是他對不同mr job的task無效

6.11 採用合適的存儲格式

6.12 數據傾斜

數據傾斜原因:1、join 傾斜 2、聚合傾斜

group by 傾斜: group by 欄位中某個欄位的值過多,導致處理這個值得rece耗時很久

解決方法:set hive.map.aggr=true;  -- 表示開啟map端聚合

set hive.groupby.skewindata=true;  注意:只能對單個欄位聚合 , 生成兩個map job ,第一個map job中map輸出結果隨機分布到rece中,每個rece做部分聚合操作,並輸出結果,這樣相同的groub key有可能被分發到不同的rece中,從而達到負載均衡的目的;第二個map job再根據預處理的數據結果按照group by key分布到rece中,這個過程可以保證相同的key被分到同一個rece中,最後完成最終的聚合操作

6.13 優化in、exists語句

使用left semi join 替換in 、exists

6.14 合並 maprece操作

multi-group by 是hive的一個非常好的特性,它使得hive中利用中間結果變更非常方便

例如:

from ( select a.status,b.school from status_update a join profilees b on (a.userid=b.suerid)) subq1

insert overwirte table a1 partition(ds='2021-03-07') 

select subq1.school,count(1) group by subq1.school

insert overwrite table b1 partition(ds='2021-03-07')

select subq1.status,count(1) group by subq1.status

上述語句使用了multi-group by特性聯系group by 2次數據,使用不同的group by key,這一特性可以減少一次maprece操作

4. Hive優化的十大方法

Hive用的好,才能從數據中挖掘出更多的信息來。用過hive的朋友,我想或多或少都有類似的經歷:一天下來,沒跑幾次hive,就到下班時間了。Hive在極大數據或者數據不平衡等情況下,表現往往一般,因此也出現了presto、spark-sql等替代品。這里重點講解hive的優化方式,例如

一. 表連接優化

二. 用insert into替換union all
如果union all的部分個數大於2,或者每個union部分數據量大,應該拆成多個insert into 語句,實際測試過程中,執行時間能提升50%。示例參考如下:

可以改寫為:

三. order by & sort by
order by : 對查詢結果進行全局排序消耗時間長,需要set hive.mapred.mode=nostrict
sort by : 局部排序,並非全局有序,提高效率。

四. transform+python
一種嵌入在hive取數流程中的自定義函數,通過transform語句可以把在hive中不方便實現的功能在python中實現,然後寫入hive表中。示例語法如下:

如果除python腳本外還有其它依賴資源,可以使用ADD ARVHIVE。

五. limit 語句快速出結果
一般情況下,Limit語句還是需要執行整個查詢語句,然後再返回部分結果。有一個配置屬性可以開啟,避免這種情況—對數據源進行抽樣

缺點:有可能部分數據永遠不會被處理到

六. 本地模式
對於小數據集,為查詢觸發執行任務消耗的時間>實際執行job的時間,因此可以通過本地模式,在單台機器上(或某些時候在單個進程上)處理所有的任務。

可以通過設置屬性hive.exec.mode.local.auto的值為true,來讓Hive在適當的時候自動啟動這個優化,也可以將這個配置寫在$HOME/.hiverc文件中。
當一個job滿足如下條件才能真正使用本地模式:

七. 並行執行
Hive會將一個查詢轉化為一個或多個階段,包括:MapRece階段、抽樣階段、合並階段、limit階段等。默認情況下,一次只執行一個階段。 不過,如果某些階段不是互相依賴,是可以並行執行的。

會比較耗系統資源。

八. 調整mapper和recer的個數

假設input目錄下有1個文件a,大小為780M,那麼hadoop會將該文件a分隔成7個塊(6個128m的塊和1個12m的塊),從而產生7個map數
假設input目錄下有3個文件a,b,c,大小分別為10m,20m,130m,那麼hadoop會分隔成4個塊(10m,20m,128m,2m),從而產生4個map數。
即如果文件大於塊大小(128m),那麼會拆分,如果小於塊大小,則把該文件當成一個塊。
map執行時間:map任務啟動和初始化的時間+邏輯處理的時間。

減少map數
若有大量小文件(小於128M),會產生多個map,處理方法是:

前面三個參數確定合並文件塊的大小,大於文件塊大小128m的,按照128m來分隔,小於128m,大於100m的,按照100m來分隔,把那些小於100m的(包括小文件和分隔大文件剩下的)進行合並。

set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; – 執行前進行小文件合並。

增加map數
當input的文件都很大,任務邏輯復雜,map執行非常慢的時候,可以考慮增加Map數,來使得每個map處理的數據量減少,從而提高任務的執行效率。
set mapred.rece.tasks=?

一般根據輸入文件的總大小,用它的estimation函數來自動計算rece的個數:rece個數 = InputFileSize / bytes per recer

九. 嚴格模式

十. 數據傾斜
表現:
任務進度長時間維持在99%(或100%),查看任務監控頁面,發現只有少量(1個或幾個)rece子任務未完成。因為其處理的數據量和其他rece差異過大。單一rece的記錄數與平均記錄數差異過大,通常可能達到3倍甚至更多。 最長時長遠大於平均時長。

原因:

解決方案:參數調節

5. Hive優化之Hive的配置參數優化

Hive是大數據領域常用的組件之一,主要用於大數據離線數倉的運算,關於Hive的性能調優在日常工作和面試中是經常涉及的一個點,因此掌握一些Hive調優是必不可少的一項技能。影響Hive效率的主要因素有數據傾斜、數據冗餘、job的IO以及不同底層引擎配置情況和Hive本身參數和HiveSQL的執行等。本文主要從建表配置參數方面對Hive優化進行講解。

1. 創建一個普通表

table test_user1(id int, name string,code string,code_id string ) ROW FORMAT DELIMITED FIELDS TERMINATED  BY ',';

2. 查看這張表的信息

DESCRIBE FORMATTED  test_user1;

我們從該表的描述信息介紹建表時的一些可優化點。

2.1 表的文件數

numFiles表示表中含有的文件數,當文件數過多時可能意味著該表的小文件過多,這時候我們可以針對小文件的問題進行一些優化,HDFS本身提供了解決方案:

(1)Hadoop Archive/HAR:將小文件打包成大文件。

(2)SEQUENCEFILE格式:將大量小文件壓縮成一個SEQUENCEFILE文件。

(3)CombineFileInputFormat:在map和rece處理之前組合小文件。

(4)HDFS Federation:HDFS聯盟,使用多個namenode節點管理文件。

除此之外,我們還可以通過設置hive的參數來合並小文件。

(1)輸入階段合並

需要更改Hive的輸入文件格式,即參數hive.input.format,默認值是org.apache.hadoop.hive.ql.io.HiveInputFormat,我們改成org.apache.hadoop.hive.ql.io.CombineHiveInputFormat。這樣比起上面對mapper數的調整,會多出兩個參數,分別是mapred.min.split.size.per.node和mapred.min.split.size.per.rack,含義是單節點和單機架上的最小split大小。如果發現有split大小小於這兩個值(默認都是100MB),則會進行合並。具體邏輯可以參看Hive源碼中的對應類。

(2)輸出階段合並

直接將hive.merge.mapfiles和hive.merge.mapredfiles都設為true即可,前者表示將map-only任務的輸出合並,後者表示將map-rece任務的輸出合並,Hive會額外啟動一個mr作業將輸出的小文件合並成大文件。另外,hive.merge.size.per.task可以指定每個task輸出後合並文件大小的期望值,hive.merge.size.smallfiles.avgsize可以指定所有輸出文件大小的均值閾值,默認值都是1GB。如果平均大小不足的話,就會另外啟動一個任務來進行合並。

2.2 表的存儲格式

通過InputFormat和OutputFormat可以看出表的存儲格式是TEXT類型,Hive支持TEXTFILE, SEQUENCEFILE, AVRO, RCFILE, ORC,以及PARQUET文件格式,可以通過兩種方式指定表的文件格式:

(1)CREATE TABLE ... STORE AS <file_format>:在建表時指定文件格式,默認是TEXTFILE

(2)ALTER TABLE ... [PARTITION partition_spec] SET FILEFORMAT <file_format>:修改具體表的文件格式

如果要改變創建表的默認文件格式,可以使用set

hive.default.fileformat=<file_format>進行配置,適用於所有表。同時也可以使用set

hive.default.fileformat.managed = <file_format>進行配置,僅適用於內部表或外部表。

擴展:不同存儲方式的情況

TEXT,

SEQUENCE和

AVRO文件是面向行的文件存儲格式,不是最佳的文件格式,因為即便只查詢一列數據,使用這些存儲格式的表也需要讀取完整的一行數據。另一方面,面向列的存儲格式(RCFILE,

ORC, PARQUET)可以很好地解決上面的問題。關於每種文件格式的說明,如下:

(1)TEXTFILE

創建表時的默認文件格式,數據被存儲成文本格式。文本文件可以被分割和並行處理,也可以使用壓縮,比如GZip、LZO或者Snappy。然而大部分的壓縮文件不支持分割和並行處理,會造成一個作業只有一個mapper去處理數據,使用壓縮的文本文件要確保文件不要過大,一般接近兩個HDFS塊的大小。

(2)SEQUENCEFILE

key/value對的二進制存儲格式,sequence文件的優勢是比文本格式更好壓縮,sequence文件可以被壓縮成塊級別的記錄,塊級別的壓縮是一個很好的壓縮比例。如果使用塊壓縮,需要使用下面的配置:set

hive.exec.compress.output=true; set io.seqfile.compression.type=BLOCK

(3)AVRO

二進制格式文件,除此之外,avro也是一個序列化和反序列化的框架。avro提供了具體的數據schema。

(4)RCFILE

全稱是Record Columnar File,首先將表分為幾個行組,對每個行組內的數據進行按列存儲,每一列的數據都是分開存儲,即先水平劃分,再垂直劃分。

(5)ORC

全稱是Optimized Row Columnar,從hive0.11版本開始支持,ORC格式是RCFILE格式的一種優化的格式,提供了更大的默認塊(256M)

(6)PARQUET

另外一種列式存儲的文件格式,與ORC非常類似,與ORC相比,Parquet格式支持的生態更廣,比如低版本的impala不支持ORC格式。

配置同樣數據同樣欄位的兩張表,以常見的TEXT行存儲和ORC列存儲兩種存儲方式為例,對比執行速度。

TEXT存儲方式

總結: 從上圖中可以看出列存儲在對指定列進行查詢時,速度更快, 建議在建表時設置列存儲的存儲方式 。

2.3 表的壓縮

對Hive表進行壓縮是常見的優化手段,一些存儲方式自帶壓縮選擇,比如SEQUENCEFILE支持三種壓縮選擇:NONE,RECORD,BLOCK。Record壓縮率低,一般建議使用BLOCK壓縮;

ORC支持三種壓縮選擇:NONE,ZLIB,SNAPPY。我們以TEXT存儲方式和ORC存儲方式為例,查看錶的壓縮情況。

配置同樣數據同樣欄位的四張表,一張TEXT存儲方式,另外三張分別是默認壓縮方式的ORC存儲、SNAPPY壓縮方式的ORC存儲和NONE壓縮方式的ORC存儲,查看在hdfs上的存儲情況:

TEXT存儲方式

默認壓縮ORC存儲方式

SNAPPY壓縮的ORC存儲方式

NONE壓縮的ORC存儲方式

總結 :可以看到ORC存儲方式將數據存放為兩個block,默認壓縮大小加起來134.69M,SNAPPY壓縮大小加起來196.67M,NONE壓縮大小加起來247.55M,TEXT存儲方式的文件大小為366.58M,且默認block兩種存儲方式分別為256M和128M,ORC默認的壓縮方式比SNAPPY壓縮得到的文件還小,原因是ORZ默認的ZLIB壓縮方式採用的是deflate壓縮演算法,比Snappy壓縮演算法得到的壓縮比高,壓縮的文件更小。 ORC不同壓縮方式之間的執行速度,經過多次測試發現三種壓縮方式的執行速度差不多,所以建議採用ORC默認的存儲方式進行存儲數據。

2.4 分桶分區

Num Buckets表示桶的數量,我們可以通過分桶和分區操作對Hive表進行優化:

對於一張較大的表,可以將它設計成分區表,如果不設置成分區表,數據是全盤掃描的,設置成分區表後,查詢時只在指定的分區中進行數據掃描,提升查詢效率。要注意盡量避免多級分區,一般二級分區足夠使用。常見的分區欄位:

(1)日期或者時間,比如year、month、day或者hour,當表中存在時間或者日期欄位時,可以使用些欄位。

(2)地理位置,比如國家、省份、城市等

(3)業務邏輯,比如部門、銷售區域、客戶等等

與分區表類似,分桶表的組織方式是將HDFS上的一張大表文件分割成多個文件。分桶是相對分區進行更細粒度的劃分,分桶將整個數據內容按照分桶欄位屬性值得hash值進行區分,分桶可以加快數據采樣,也可以提升join的性能(join的欄位是分桶欄位),因為分桶可以確保某個key對應的數據在一個特定的桶內(文件),所以巧妙地選擇分桶欄位可以大幅度提升join的性能。通常情況下,分桶欄位可以選擇經常用在過濾操作或者join操作的欄位。

創建分桶表

create

table test_user_bucket(id int, name string,code string,code_id string )

clustered by(id) into 3 buckets ROW FORMAT DELIMITED FIELDS TERMINATED 

BY ',';

查看描述信息

DESCRIBE FORMATTED test_user_bucket

多出了如下信息

查看該表的hdfs

同樣的數據查看普通表和分桶表查詢效率

普通表

分桶表

普通表是全表掃描,分桶表在按照分桶欄位的hash值分桶後,根據join欄位或者where過濾欄位在特定的桶中進行掃描,效率提升。

本文首發於: 數棧研習社

數棧是雲原生—站式數據中台PaaS,我們在github上有一個有趣的開源項目: FlinkX

FlinkX是一個基於Flink的批流統一的數據同步工具,既可以採集靜態的數據,比如MySQL,HDFS等,也可以採集實時變化的數據,比如MySQL

binlog,Kafka等,是全域、異構、批流一體的數據同步引擎,大家如果有興趣,歡迎來github社區找我們玩~

6. 大數據開發工程師Hive(Hive如何進行優化)

1數據存儲及壓縮優化

針對hive中表的存儲格式通常有textfile和orc,壓縮格式一般使用snappy。相比於 textfile格式存儲,orc佔有更少的存儲。因為hive底層使用MR計算架構,數據流是hdfs到磁碟再到hdfs,而且會有很多次IO讀寫操作,所以使用orc數據格式和snappy壓縮策略可以降低IO讀寫,還能降低網路傳輸量,這樣在一定程度上可以節省存儲空間,還能提升hql的執行效率;

2 Hive Job優化

①調節Jvm參數,重用Jvm;

②合理設置Map個數;

③合理設置Rece個數;

3 Sql語法優化

建表優化

1) Hive創建表的時候,可以建分區表,分桶表;

2) Hive創建表的時候,可以指定數據存儲格式:TextFile、SequenceFile、RCfile 、ORCfile;

查詢時優化

1) 列裁剪,在查詢時只讀取需要的列,避免全列掃描,不要使用select * from table;

2) 分區裁剪:在查詢時只讀取需要分區的數據,避免全表掃描;

3) 開啟謂詞下推:set hive.optimize.ppd = true,默認是true:

a. 將Sql語句中的where謂詞邏輯都盡可能提前執行,減少下游處理的數據量;

4) 大表join小表:

a. 開啟MapJoin:set hive.auto.convert.join=true:

b. MapJoin是將Join雙方比較小的那個表直接分發到各個Map進程的內存中,在 Map進程中進行Join操作, 這樣就不用進行Rece步驟 ,從而提高了速度( 大表left join小表才有效 ,小表left join大表會失效);

5) 大表join大表:

a. SMB Join :Sort Merge Bucket Join(數據不僅分桶了,而且每個桶數據是排好序了);

b. 開啟SMB Join之後,底層是根據兩個表join欄位進行分桶存儲,這樣的話,兩張表就變為了基於桶之間join關聯查詢,而不是基於整張表的join,減少了笛卡爾積;

6) 少用in,用left semi join替代in:

a. 原始寫法:select a.id, a.name from a where a.id in (select b.id from b);

b. 用join改寫:select a.id, a.name from a join b on a.id = b.id;

c. left semi join改寫:select a.id, a.name from a left semi join b on a.id = b.id;

7) 用union all代替union,因為union all不需要去重,也不需要排序,效率高於union;

(每天1小題,進步1點點)

7. hive運行sql rece 為1 ,跑不動怎麼處理

1.jpg 優化可以從幾個方面著手:1. 好的模型設計事半功倍。2. 解決數據傾斜問題。3. 減少job數。4. 設置合理的map rece的task數,能有效提升性能。(比如,10w+級別的計算,用160個rece,那是相當的浪費,1個足夠)。5. 自己動手寫sql解決數據傾斜問題是個不錯的選擇。set hive.groupby.skewindata=true;這是通用的演算法優化,但演算法優化總是漠視業務,習慣性提供通用的解決方法。 Etl開發人員更了解業務,更了解數據,所以通過業務邏輯解決傾斜的方法往往更精確,更有效。6. 對count(distinct)採取漠視的方法,尤其數據大的時候很容易產生傾斜問題,不抱僥幸心理。自己動手,豐衣足食。7. 對小文件進行合並,是行至有效的提高調度效率的方法,假如我們的作業設置合理的文件數,對雲梯的整體調度效率也會產生積極的影響。8. 優化時把握整體,單個作業最優不如整體最優。

8. hive sql cpu消耗大怎麼優化

經常出現CPU佔用100%的情況,主要問題可能發生在下面的某些方面: 

CPU佔用率高的九種可能 

1、防殺毒軟體造成故障 

由於新版的KV、金山、瑞星都加入了對網頁、插件、郵件的隨機監控,無疑增大了系統負擔。處理方式:基本上沒有合理的處理方式,盡量使用最少的監控服務吧,或者,升級你的硬體配備。 

2、驅動沒有經過認證,造成CPU資源佔用100% 

大量的測試版的驅動在網上泛濫,造成了難以發現的故障原因。 處理方式:尤其是顯卡驅動特別要注意,建議使用微軟認證的或由官方發布的驅動,並且嚴格核對型號、版本。 

3、病毒、木馬造成 

大量的蠕蟲病毒在系統內部迅速復制,造成CPU佔用資源率據高不下。解決辦法:用可靠的殺毒軟體徹底清理系統內存和本地硬碟,並且打開系統設置軟體,察看有無異常啟動的程序。經常性更新升級殺毒軟體和防火牆,加強防毒意識,掌握正確的防殺毒知識。 

4、控制面板—管理工具—服務—RISING REALTIME MONITOR SERVICE點滑鼠右鍵,改為手動。 

5、開始->;運行->;msconfig->;啟動,關閉不必要的啟動項,重啟。 

6、查看「svchost」進程。 

svchost.exe是Windows XP系統的一個核心進程。svchost.exe不單單只出現在Windows XP中,在使用NT內核的Windows系統中都會有svchost.exe的存在。一般在Windows 2000中svchost.exe進程的數目為2個,而在Windows XP中svchost.exe進程的數目就上升到了4個及4個以上。 

7、查看網路連接。主要是網卡。