0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

大數(shù)據(jù)從業(yè)者必知必會的Hive SQL調(diào)優(yōu)技巧

京東云 ? 來源:jf_75140285 ? 作者:jf_75140285 ? 2024-09-24 13:30 ? 次閱讀

大數(shù)據(jù)從業(yè)者必知必會的Hive SQL調(diào)優(yōu)技巧

摘要:在大數(shù)據(jù)領(lǐng)域中,Hive SQL被廣泛應(yīng)用于數(shù)據(jù)倉庫的數(shù)據(jù)查詢和分析。然而,由于數(shù)據(jù)量龐大和復(fù)雜的查詢需求,Hive SQL查詢的性能往往不盡人意。本文針對Hive SQL的性能優(yōu)化進(jìn)行深入研究,提出了一系列可行的調(diào)優(yōu)方案,并給出了相應(yīng)的優(yōu)化案例和優(yōu)化前后的SQL代碼。通過合理的優(yōu)化策略和技巧,能夠顯著提升Hive SQL的執(zhí)行效率和響應(yīng)速度。

關(guān)鍵詞:Hive SQL;性能優(yōu)化;調(diào)優(yōu)方案;優(yōu)化案例

1. 引言

隨著大數(shù)據(jù)時代的到來,數(shù)據(jù)分析和挖掘變得越來越重要。Hive作為Hadoop生態(tài)系統(tǒng)中的數(shù)據(jù)倉庫工具,扮演著重要的角色。然而,由于數(shù)據(jù)量龐大和查詢復(fù)雜性,Hive SQL查詢的執(zhí)行效率往往較低。因此,深入了解Hive SQL調(diào)優(yōu)技巧對于數(shù)據(jù)工程師和數(shù)據(jù)分析師來說至關(guān)重要。

2. 先做個自我反思

很多時候, Hive SQL 運(yùn)行得慢是由開發(fā)人員對于使用的數(shù)據(jù)了解不夠以及一些不良的使用習(xí)慣引起的。

?真的需要掃描這么多分區(qū)嗎?

比如,對于銷售明細(xì)事務(wù)表來說,掃描一年的分區(qū)和掃描一周的分區(qū)所帶來的計算、 IO 開銷完全是兩個量級,所耗費(fèi)的時間肯定也是不同的。作為開發(fā)人員,我們需要仔細(xì)考慮業(yè)務(wù)的需求,盡量不要浪費(fèi)計算和存儲資源。

?習(xí)慣使用select *這樣的方式,而不是用到哪些列就指定哪些列嗎?

比如,select coll, col2 from your_table ,另外, where 條件中也盡量添加過濾條件,以去掉無關(guān)的數(shù)據(jù)行,從而減少整個 MapReduce 任務(wù)中需要處理、分發(fā)的數(shù)據(jù)量。

?需要計算的指標(biāo)真的需要從數(shù)據(jù)倉庫的公共明細(xì)層來自行匯總嗎?

是不是數(shù)倉團(tuán)隊開發(fā)的公共匯總層已經(jīng)可以滿足你的需求?對于通用的、管理者駕駛艙相關(guān)的指標(biāo)等通常設(shè)計良好的數(shù)據(jù)倉庫公共層肯定已經(jīng)包含了,直接使用即可。

??

3 查詢優(yōu)化

3.1 盡量原子化操作

盡量避免一個SQL包含復(fù)雜邏輯,可以使用中間表來完成復(fù)雜的邏輯。建議對作業(yè)進(jìn)行合理拆分,降低作業(yè)出問題重跑時資源的浪費(fèi)和下游時效的影響。

3.2 使用合適的數(shù)據(jù)類型

選擇合適的數(shù)據(jù)類型可以減小存儲空間和提高查詢效率。例如,將字符串類型轉(zhuǎn)換為整型類型可以節(jié)省存儲空間并加快查詢速度。

優(yōu)化案例

優(yōu)化前:

SELECT * FROM table WHERE age = '30'; 

優(yōu)化后:

SELECT * FROM table WHERE age = 30;

3.3 避免全表掃描

盡量避免全表掃描,可以通過WHERE子句篩選出需要的數(shù)據(jù)行,或者使用LIMIT子句限制返回結(jié)果的數(shù)量。

反面案例

天天全表掃描計算所有歷史數(shù)據(jù)。 map數(shù)超20萬。

Select * from table where dt<=’{TX_DATE}’

優(yōu)化案例1

優(yōu)化前:

--優(yōu)化前副表的過濾條件寫在where后面,會導(dǎo)致先全表關(guān)聯(lián)再過濾分區(qū)。

select a.* from test1 a left join test2 b on a.uid = b.uid where a.ds='2020-08-10' and b.ds='2020-08-10' 

優(yōu)化后:

select a.* from test1 a left join test2 b on (b.uid is not null and a.uid = b.uid and b.ds='2020-08-10') where a.ds='2020-08-10'

優(yōu)化案例2

利用max函數(shù)取表最大分區(qū),造成全表掃描。

優(yōu)化前:

Select max(dt) from table

優(yōu)化后:

使用自定義(show partition 或 hdfs dfs –ls )的方式替代max(dt)

3.4 使用分區(qū)

數(shù)據(jù)分區(qū)是一種將數(shù)據(jù)按照某個字段進(jìn)行分組存儲的技術(shù),可以有效減少查詢時的數(shù)據(jù)掃描量。通過分區(qū)字段進(jìn)行數(shù)據(jù)過濾,可以只對目標(biāo)分區(qū)進(jìn)行查詢,加快查詢速度。

優(yōu)化案例

優(yōu)化前:

SELECT * FROM table WHERE date = '2021-01-01' AND region = 'A';

優(yōu)化后:

SELECT * FROM table WHERE partition_date = '2021-01-01' AND partition_region = 'A';

反面案例

代碼寫死日期,一次性不合理掃描2年+日志數(shù)據(jù)。map數(shù)超20萬,而且會越來越大,直到跑不出來。

Select * from table where src_mark=’23’ and dt between ‘2020-05-16’ and ‘{TX_DATE}’ and scr_code is not null

3.5 使用索引

在Hive SQL中,可以通過創(chuàng)建索引來加速查詢操作。通過在關(guān)鍵字段上創(chuàng)建索引,可以減少數(shù)據(jù)掃描和過濾的時間,提高查詢性能。

優(yōu)化案例

優(yōu)化前:

SELECT * FROM table WHERE region = 'A' AND status = 'ACTIVE';

優(yōu)化后:

CREATE INDEX idx_region_status ON table (region, status);
SELECT * FROM table WHERE region = 'A' AND status = 'ACTIVE';

3.6 查詢重寫

查詢重寫是一種通過改變查詢語句的結(jié)構(gòu)或使用優(yōu)化的查詢方式,來改善查詢的性能的技巧??梢酝ㄟ^重寫子查詢、使用JOIN代替IN/EXISTS子查詢等方法來優(yōu)化查詢。

優(yōu)化案例

優(yōu)化前:

SELECT * FROM table1 WHERE id IN (SELECT id FROM table2 WHERE region = 'A');

優(yōu)化后:

SELECT * FROM table1 t1 JOIN (SELECT id FROM table2 WHERE region = 'A') t2 ON t1.id = t2.id;

3.7 謂詞下推

謂詞下推是一種將過濾條件盡早應(yīng)用于查詢計劃中的技術(shù)(即SQL語句中的WHERE謂詞邏輯都盡可能提前執(zhí)行),減少下游處理的數(shù)據(jù)量。通過將過濾條件下推至數(shù)據(jù)源,可以減少查詢數(shù)據(jù)量,提升查詢性能。

優(yōu)化案例

優(yōu)化前:

select a.*,b.* from a join b  on a.name=b.name where a.age>30

優(yōu)化后:

SELECT a.*, b.* FROM ( SELECT * FROM a WHERE age > 30 ) a JOIN b ON a.name = b.name

3.8 不要用COUNT DISTINCT

COUNT DISTINCT操作需要用一個Reduce Task來完成,這一個Reduce需要處理的數(shù)據(jù)量太大,就會導(dǎo)致整個Job很難完成,一般COUNT DISTINCT使用先GROUP BY再COUNT的方式替換,雖然會多用一個Job來完成,但在數(shù)據(jù)量大的情況下,這個絕對是值得的。

優(yōu)化案例

優(yōu)化前:

select count(distinct uid) from test where ds='2020-08-10' and uid is not null

優(yōu)化后:

select count(a.uid) from (select uid from test where uid is not null and ds = '2020-08-10' group by uid) a

3.9 使用with as

拖慢hive查詢效率出了join產(chǎn)生的shuffle以外,還有一個就是子查詢,在SQL語句里面盡量減少子查詢。with as是將語句中用到的子查詢事先提取出來(類似臨時表),使整個查詢當(dāng)中的所有模塊都可以調(diào)用該查詢結(jié)果。使用with as可以避免Hive對不同部分的相同子查詢進(jìn)行重復(fù)計算。

優(yōu)化案例

優(yōu)化前:

select a.* from test1 a left join test2 b on a.uid = b.uid where a.ds='2020-08-10' and b.ds='2020-08-10'

優(yōu)化后:

with b as select uid from test2 where ds = '2020-08-10' and uid is not null select a.* from test1 a left join b on a.uid = b.uid where a.ds='2020-08-10' and a.uid is not null

3.10 大表Join小表

在編寫具有Join操作的查詢語句時,有一項重要的原則需要遵循:應(yīng)當(dāng)將記錄較少的表或子查詢放置在Join操作符的左側(cè)。這樣做有助于減少數(shù)據(jù)量,提高查詢效率,并有效降低內(nèi)存溢出錯誤的發(fā)生概率。

如果未指定MapJoin,或者不符合MapJoin的條件,Hive解析器將會將Join操作轉(zhuǎn)換成Common Join。這意味著Join操作將在Reduce階段完成,由此可能導(dǎo)致數(shù)據(jù)傾斜的問題。為了避免這種情況,可以通過使用MapJoin將小表完全加載到內(nèi)存中,并在Map端執(zhí)行Join操作,從而避免將Join操作留給Reducer階段處理。這種策略有效地減少了數(shù)據(jù)傾斜的風(fēng)險。

優(yōu)化案例

--設(shè)置自動選擇Mapjoin

set hive.auto.convert.join = true; 默認(rèn)為true

--大表小表的閾值設(shè)置(默認(rèn)25M以下認(rèn)為是小表):

set hive.mapjoin.smalltable.filesize=25000000;

3.11 大表Join大表

3.11.1 空key過濾

有時候,連接操作超時可能是因為某些key對應(yīng)的數(shù)據(jù)量過大。相同key的數(shù)據(jù)被發(fā)送到相同的reducer上,由此導(dǎo)致內(nèi)存不足。在這種情況下,我們需要仔細(xì)分析這些異常的key。通常,這些key對應(yīng)的數(shù)據(jù)可能是異常的,因此我們需要在SQL語句中進(jìn)行適當(dāng)?shù)倪^濾。

3.11.2 空key轉(zhuǎn)換

當(dāng)某個key為空時,盡管對應(yīng)的數(shù)據(jù)很豐富,但并非異常情況。在執(zhí)行join操作時,這些數(shù)據(jù)必須包含在結(jié)果集中。為實現(xiàn)這一目的,可以考慮將表a中那些key為空的字段賦予隨機(jī)值,以確保數(shù)據(jù)能夠均勻、隨機(jī)地分布到不同的reducer上。

3.12 避免笛卡爾積

在執(zhí)行join操作時,若不添加有效的on條件或者使用無效的on條件,而是采用where條件,可能會面臨關(guān)聯(lián)列包含大量空值或者重復(fù)值的情況。這可能導(dǎo)致Hive只能使用一個reducer來完成操作,從而引發(fā)笛卡爾積和數(shù)據(jù)膨脹問題。因此,在進(jìn)行join時,務(wù)必注意確保使用有效的關(guān)聯(lián)條件,以免由于數(shù)據(jù)的空值或重復(fù)值而影響操作性能。

優(yōu)化案例

優(yōu)化前:

SELECT * FROM A, B; 

--在優(yōu)化前的SQL代碼中,使用了隱式的內(nèi)連接(JOIN),沒有明確指定連接條件,導(dǎo)致產(chǎn)生了笛卡爾積

優(yōu)化后;

SELECT * FROM A CROSS JOIN B;

在優(yōu)化后的SQL代碼中,使用了明確的交叉連接(CROSS JOIN),確保只返回A和B表中的所有組合,而不會產(chǎn)生重復(fù)的行。 通過明確指定連接方式,可以避免不必要的笛卡爾積操作,提高查詢效率。

4. 數(shù)據(jù)加載和轉(zhuǎn)換

4.1 使用壓縮格式

在數(shù)據(jù)加載過程中,選擇合適的數(shù)據(jù)存儲格式(對于結(jié)構(gòu)化數(shù)據(jù),可以選擇Parquet或ORC等列式存儲格式;對于非結(jié)構(gòu)化數(shù)據(jù),可以選擇TextFile或SequenceFile等格式),可以提高查詢性能和減少存儲空間。

優(yōu)化案例

優(yōu)化前:

LOAD DATA INPATH '/path/to/data' INTO TABLE table;

優(yōu)化后:

LOAD DATA INPATH '/path/to/data' INTO TABLE table STORED AS ORC;

4.2 數(shù)據(jù)轉(zhuǎn)換和過濾

在數(shù)據(jù)加載之前,對數(shù)據(jù)進(jìn)行轉(zhuǎn)換和過濾可以減小數(shù)據(jù)量,并加快查詢速度。例如,可以使用Hive內(nèi)置函數(shù)對數(shù)據(jù)進(jìn)行清洗和轉(zhuǎn)換,以滿足特定的查詢需求。

優(yōu)化案例

優(yōu)化前:

SELECT * FROM table WHERE name LIKE '%John%'; 

優(yōu)化后:

SELECT * FROM table WHERE name = 'John';

4.3 多次INSERT單次掃描表

默認(rèn)情況下,Hive會執(zhí)行多次表掃描。因此,如果要在某張hive表中執(zhí)行多個操作,建議使用一次掃描并使用該掃描來執(zhí)行多個操作。

比如將一張表的數(shù)據(jù)多次查詢出來裝載到另外一張表中。如下面的示例,表my_table是一個分區(qū)表,分區(qū)字段為dt,如果需要在表中查詢2個特定的分區(qū)日期數(shù)據(jù),并將記錄裝載到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';

在以上查詢中,Hive將掃描表2次,為了避免這種情況,我們可以使用下面的方式:

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

這樣可以確保只對my_table表執(zhí)行一次掃描,從而可以大大減少執(zhí)行的時間和資源。

5. 性能評估和優(yōu)化

5.1 使用EXPLAIN命令

使用EXPLAIN命令可以分析查詢計劃并評估查詢的性能。通過查看查詢計劃中的資源消耗情況,可以找出潛在的性能問題,并進(jìn)行相應(yīng)的優(yōu)化。

優(yōu)化案例

優(yōu)化前:

EXPLAIN SELECT * FROM table WHERE age = 30; 

優(yōu)化后:

EXPLAIN SELECT * FROM table WHERE age = 30 AND partition = 'partition1'; 

5.2 調(diào)整并行度和資源配置

根據(jù)集群的配置和資源情況,合理調(diào)整Hive查詢的并行度和資源分配,可以提高查詢的并發(fā)性和整體性能。通過設(shè)置參數(shù)hive.exec.parallel值為true,就可以開啟并發(fā)執(zhí)行。不過,在共享集群中,需要注意下,如果job中并行階段增多,那么集群利用率就會增加。建議在數(shù)據(jù)量大,sql很長的時候使用,數(shù)據(jù)量小,sql比較的小開啟有可能還不如之前快。

優(yōu)化案例

優(yōu)化前:

SET hive.exec.parallel=true; 

優(yōu)化后:

SET hive.exec.parallel=false; SET hive.exec.reducers.max=10;

6. 數(shù)據(jù)傾斜

任務(wù)進(jìn)度長時間維持在99%(或100%),檢查任務(wù)監(jiān)控頁面后發(fā)現(xiàn)僅有少量(1個或幾個)reduce子任務(wù)未完成。這些未完成的reduce子任務(wù)由于處理的數(shù)據(jù)量與其他reduce子任務(wù)存在顯著差異。具體而言,單一reduce子任務(wù)的記錄數(shù)與平均記錄數(shù)之間存在顯著差異,通??蛇_(dá)到3倍甚至更多。此外,未完成的reduce子任務(wù)的最長時長明顯超過了平均時長。主要原因可以歸結(jié)為以下幾種:

6.1 空值引發(fā)的數(shù)據(jù)傾斜

在數(shù)據(jù)倉庫中存在大量空值(NULL)的情況下,導(dǎo)致數(shù)據(jù)分布不均勻的現(xiàn)象。這種數(shù)據(jù)傾斜可能會對數(shù)據(jù)分析和計算產(chǎn)生負(fù)面影響。當(dāng)數(shù)據(jù)倉庫中某個字段存在大量空值時,這些空值會在數(shù)據(jù)計算和聚合操作中引起不平衡的情況。例如,在使用聚合函數(shù)(如SUM、COUNT、AVG等)對該字段進(jìn)行計算時,空值并不會被包括在內(nèi),導(dǎo)致計算結(jié)果與實際情況不符。數(shù)據(jù)傾斜會導(dǎo)致部分reduce子任務(wù)負(fù)載過重,而其他reduce子任務(wù)負(fù)載較輕,從而影響任務(wù)的整體性能。這可能導(dǎo)致任務(wù)進(jìn)度長時間維持在99%(或100%),但仍有少量reduce子任務(wù)未完成的情況。

優(yōu)化方案

第一種:可以直接不讓null值參與join操作,即不讓null值有shuffle階段。

第二種:因為null值參與shuffle時的hash結(jié)果是一樣的,那么我們可以給null值隨機(jī)賦值,這樣它們的hash結(jié)果就不一樣,就會進(jìn)到不同的reduce中。

6.2 不同數(shù)據(jù)類型引發(fā)的數(shù)據(jù)傾斜

在數(shù)據(jù)倉庫中,不同數(shù)據(jù)類型的字段可能具有不同的取值范圍和分布情況。例如,某個字段可能是枚舉類型,只有幾個固定的取值;而另一個字段可能是連續(xù)型數(shù)值,取值范圍較大。當(dāng)進(jìn)行數(shù)據(jù)計算和聚合操作時,如果不同數(shù)據(jù)類型的字段在數(shù)據(jù)分布上存在明顯的差異,就會導(dǎo)致數(shù)據(jù)傾斜。數(shù)據(jù)傾斜會導(dǎo)致部分reduce子任務(wù)負(fù)載過重,而其他reduce子任務(wù)負(fù)載較輕,從而影響任務(wù)的整體性能。這可能導(dǎo)致任務(wù)進(jìn)度長時間維持在99%(或100%),但仍有少量reduce子任務(wù)未完成的情況。

優(yōu)化方案

如果key字段既有string類型也有int類型,默認(rèn)的hash就都會按int類型來分配,那我們直接把int類型都轉(zhuǎn)為string就好了,這樣key字段都為string,hash時就按照string類型分配了。

6.3 不可拆分大文件引發(fā)的數(shù)據(jù)傾斜

在Hadoop分布式計算框架中,數(shù)據(jù)通常會被切分成多個數(shù)據(jù)塊進(jìn)行并行處理。然而,當(dāng)遇到一些無法被切分的大文件時,這些大文件會被作為一個整體分配給一個reduce任務(wù)進(jìn)行處理,而其他reduce任務(wù)則可能得到較小的數(shù)據(jù)量。這導(dǎo)致部分reduce任務(wù)負(fù)載過重,而其他任務(wù)負(fù)載較輕,從而影響任務(wù)的整體性能。

優(yōu)化方案

這種數(shù)據(jù)傾斜問題沒有什么好的解決方案,只能將使用GZIP壓縮等不支持文件分割的文件轉(zhuǎn)為bzip和zip等支持文件分割的壓縮方式。

所以,我們在對文件進(jìn)行壓縮時,為避免因不可拆分大文件而引發(fā)數(shù)據(jù)讀取的傾斜,在數(shù)據(jù)壓縮的時候可以采用bzip2和Zip等支持文件分割的壓縮算法。

6.4 數(shù)據(jù)膨脹引發(fā)的數(shù)據(jù)傾斜

數(shù)據(jù)膨脹通常是由于某些數(shù)據(jù)在倉庫中存在大量冗余、重復(fù)或者拆分產(chǎn)生的。當(dāng)這些數(shù)據(jù)被用于計算和聚合操作時,會導(dǎo)致部分reduce子任務(wù)負(fù)載過重,而其他reduce子任務(wù)負(fù)載較輕,從而影響任務(wù)的整體性能。

優(yōu)化方案

在Hive中可以通過參數(shù) hive.new.job.grouping.set.cardinality 配置的方式自動控制作業(yè)的拆解,該參數(shù)默認(rèn)值是30。表示針對grouping sets/rollups/cubes這類多維聚合的操作,如果最后拆解的鍵組合大于該值,會啟用新的任務(wù)去處理大于該值之外的組合。如果在處理數(shù)據(jù)時,某個分組聚合的列有較大的傾斜,可以適當(dāng)調(diào)小該值。

6.5 表連接時引發(fā)的數(shù)據(jù)傾斜

在數(shù)據(jù)倉庫中,表連接是常用的操作,用于將不同表中的數(shù)據(jù)進(jìn)行關(guān)聯(lián)和合并。然而,當(dāng)連接鍵在不同表中的數(shù)據(jù)分布不均勻時,就會導(dǎo)致連接結(jié)果中某些連接鍵對應(yīng)的數(shù)據(jù)量遠(yuǎn)大于其他連接鍵的數(shù)據(jù)量。這會導(dǎo)致部分reduce任務(wù)負(fù)載過重,而其他任務(wù)負(fù)載較輕,從而影響任務(wù)的整體性能。

優(yōu)化方案

通常做法是將傾斜的數(shù)據(jù)存到分布式緩存中,分發(fā)到各個Map任務(wù)所在節(jié)點。在Map階段完成join操作,即MapJoin,這避免了 Shuffle,從而避免了數(shù)據(jù)傾斜。

6.6 確實無法減少數(shù)據(jù)量引發(fā)的數(shù)據(jù)傾斜

在某些情況下,數(shù)據(jù)的數(shù)量本身就非常龐大,例如某些業(yè)務(wù)場景中的大數(shù)據(jù)集,或者歷史數(shù)據(jù)的積累等。在這種情況下,即使采取了數(shù)據(jù)預(yù)處理、數(shù)據(jù)分區(qū)等措施,也無法減少數(shù)據(jù)的數(shù)量。

優(yōu)化方案

這類問題最直接的方式就是調(diào)整reduce所執(zhí)行的內(nèi)存大小。

調(diào)整reduce的內(nèi)存大小使用mapreduce.reduce.memory.mb這個配置。

7. 合并小文件

在HDFS中,每個小文件對象約占150字節(jié)的元數(shù)據(jù)空間,如果有大量的小文件存在,將會占用大量的內(nèi)存資源。這將嚴(yán)重限制NameNode節(jié)點的內(nèi)存容量,進(jìn)而影響整個集群的擴(kuò)展能力。從Hive的角度來看,小文件會導(dǎo)致產(chǎn)生大量的Map任務(wù),每個Map任務(wù)都需要啟動一個獨(dú)立的JVM來執(zhí)行。這些任務(wù)的初始化、啟動和執(zhí)行會消耗大量的計算資源,嚴(yán)重影響性能,因為每個小文件都需要進(jìn)行一次磁盤IO操作。

因此,我強(qiáng)烈建議避免使用包含大量小文件的數(shù)據(jù)源。相反,我們應(yīng)該進(jìn)行小文件合并操作,以減少查詢過程中的磁盤IO次數(shù),從而提高查詢效率。通過合并小文件,我們可以將多個小文件合并成一個較大的文件,從而減少對磁盤的IO訪問次數(shù)。這樣可以降低系統(tǒng)資源的消耗,提高查詢性能。

因此,在構(gòu)建數(shù)據(jù)倉庫時,應(yīng)該盡可能使用較大的文件來存儲數(shù)據(jù),避免大量小文件的產(chǎn)生。如果已經(jīng)存在大量小文件,可以考慮進(jìn)行小文件合并操作,以優(yōu)化數(shù)據(jù)存儲和查詢性能。這樣可以提高Hive查詢的效率,減少資源的浪費(fèi),并保證系統(tǒng)的穩(wěn)定性和可擴(kuò)展性。

7.1 Hive引擎合并小文件參數(shù)

--是否和并Map輸出文件,默認(rèn)true

set hive.merge.mapfiles = true;

--是否合并 Reduce 輸出文件,默認(rèn)false

set hive.merge.mapredfiles = true;

--合并文件的大小,默認(rèn)256000000字節(jié)

set hive.merge.size.per.task = 256000000;

--當(dāng)輸出文件的平均大小小于該值時,啟動一個獨(dú)立的map-reduce任務(wù)進(jìn)行文件merge,默認(rèn)16000000字節(jié)

set hive.merge.smallfiles.avgsize = 256000000;

7.2 Spark引擎合并小文件參數(shù),所以盡量將MR切換成Spark

--是否合并小文件,默認(rèn)true

conf spark.sql.hive.mergeFiles=true;

8. 結(jié)論

本論文介紹了大數(shù)據(jù)從業(yè)者必備的Hive SQL調(diào)優(yōu)技巧,包括查詢優(yōu)化、數(shù)據(jù)分區(qū)和索引、數(shù)據(jù)加載和轉(zhuǎn)換等方面。通過深入理解Hive SQL語言和優(yōu)化策略,開發(fā)人員可以提升查詢效率和性能。通過優(yōu)化案例和優(yōu)化前后的SQL代碼,展示了每種優(yōu)化方案的實際應(yīng)用效果。

附:實踐案例

一、背景

公司的線上平臺每天產(chǎn)生大量的用戶數(shù)據(jù),包括用戶行為、訂單信息等。為了更好地分析用戶行為和業(yè)務(wù)趨勢,我們需要對數(shù)據(jù)進(jìn)行復(fù)雜的查詢操作。原始的Hive SQL語句在執(zhí)行時存在性能瓶頸,因此我們決定對其進(jìn)行優(yōu)化。

二、原始SQL語句

原始的Hive SQL語句如下:

SELECT * FROM user_data WHERE user_id IN (SELECT user_id FROM order_data WHERE order_date >= '2022-01-01')

這個查詢語句的目的是從user_data表中選取所有在order_data表中最近一個月有訂單的用戶數(shù)據(jù)。由于user_data表和order_data表的數(shù)據(jù)量都很大,這個查詢語句執(zhí)行時間較長,存在性能瓶頸。

三、優(yōu)化策略

針對原始SQL語句的性能瓶頸,我們采取了以下優(yōu)化策略:

使用Spark計算引擎:Spark是一種高效的分布式計算框架,可以與Hive SQL集成使用來提高查詢效率。我們將使用Spark計算引擎來執(zhí)行查詢。

使用JOIN操作:將兩個表通過JOIN操作連接起來,可以減少數(shù)據(jù)的傳輸和計算開銷。我們將使用JOIN操作來連接user_data表和order_data表。

使用過濾條件:在查詢過程中,使用過濾條件可以減少數(shù)據(jù)的處理量。我們將使用過濾條件來篩選出符合條件的用戶數(shù)據(jù)。

四、優(yōu)化后的SQL語句

基于上述優(yōu)化策略,我們優(yōu)化后的Hive SQL語句如下:

SELECT u.* FROM user_data u JOIN (SELECT user_id FROM order_data WHERE order_date >= '2022-01-01') o ON u.user_id = o.user_id

這個查詢語句使用了JOIN操作將user_data表和子查詢結(jié)果連接起來,并通過過濾條件篩選出符合條件的用戶數(shù)據(jù)。同時,我們使用了Spark計算引擎來執(zhí)行查詢。

五、性能對比

我們對優(yōu)化前后的SQL語句進(jìn)行了性能對比。以下是性能對比的結(jié)果:

執(zhí)行時間:優(yōu)化后的SQL語句執(zhí)行時間比原始SQL語句減少了約50%。

數(shù)據(jù)傳輸量:優(yōu)化后的SQL語句減少了數(shù)據(jù)的傳輸量,提高了數(shù)據(jù)處理的效率。

內(nèi)存消耗:優(yōu)化后的SQL語句使用了Spark計算引擎,可以更好地利用內(nèi)存資源,提高了查詢性能。

通過對比可以看出,優(yōu)化后的SQL語句在執(zhí)行時間、數(shù)據(jù)傳輸量和內(nèi)存消耗等方面都取得了顯著的提升。

審核編輯 黃宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • SQL
    SQL
    +關(guān)注

    關(guān)注

    1

    文章

    751

    瀏覽量

    43902
  • 大數(shù)據(jù)
    +關(guān)注

    關(guān)注

    64

    文章

    8811

    瀏覽量

    137003
收藏 人收藏

    評論

    相關(guān)推薦

    智能調(diào)優(yōu),使步進(jìn)電機(jī)安靜而高效地運(yùn)行

    電子發(fā)燒友網(wǎng)站提供《智能調(diào)優(yōu),使步進(jìn)電機(jī)安靜而高效地運(yùn)行.pdf》資料免費(fèi)下載
    發(fā)表于 09-24 11:08 ?0次下載
    智能<b class='flag-5'>調(diào)</b><b class='flag-5'>優(yōu)</b>,使步進(jìn)電機(jī)安靜而高效地運(yùn)行

    MMC SW調(diào)優(yōu)算法

    電子發(fā)燒友網(wǎng)站提供《MMC SW調(diào)優(yōu)算法.pdf》資料免費(fèi)下載
    發(fā)表于 09-20 11:14 ?0次下載
    MMC SW<b class='flag-5'>調(diào)</b><b class='flag-5'>優(yōu)</b>算法

    TAS58xx系列通用調(diào)優(yōu)指南

    電子發(fā)燒友網(wǎng)站提供《TAS58xx系列通用調(diào)優(yōu)指南.pdf》資料免費(fèi)下載
    發(fā)表于 09-14 10:49 ?0次下載
    TAS58xx系列通用<b class='flag-5'>調(diào)</b><b class='flag-5'>優(yōu)</b>指南

    AM6xA ISP調(diào)優(yōu)指南

    電子發(fā)燒友網(wǎng)站提供《AM6xA ISP調(diào)優(yōu)指南.pdf》資料免費(fèi)下載
    發(fā)表于 09-07 09:52 ?0次下載
    AM6xA ISP<b class='flag-5'>調(diào)</b><b class='flag-5'>優(yōu)</b>指南

    OSPI控制器PHY調(diào)優(yōu)算法

    電子發(fā)燒友網(wǎng)站提供《OSPI控制器PHY調(diào)優(yōu)算法.pdf》資料免費(fèi)下載
    發(fā)表于 08-30 11:12 ?0次下載
    OSPI控制器PHY<b class='flag-5'>調(diào)</b><b class='flag-5'>優(yōu)</b>算法

    深度解析JVM調(diào)優(yōu)實踐應(yīng)用

    Tomcat自身的調(diào)優(yōu)是針對conf/server.xml中的幾個參數(shù)的調(diào)優(yōu)設(shè)置。首先是對這幾個參數(shù)的含義要有深刻而清楚的理解。
    的頭像 發(fā)表于 04-01 10:24 ?344次閱讀
    深度解析JVM<b class='flag-5'>調(diào)</b><b class='flag-5'>優(yōu)</b>實踐應(yīng)用

    鴻蒙開發(fā)實戰(zhàn):【性能調(diào)優(yōu)組件】

    性能調(diào)優(yōu)組件包含系統(tǒng)和應(yīng)用調(diào)優(yōu)框架,旨在為開發(fā)者提供一套性能調(diào)優(yōu)平臺,可以用來分析內(nèi)存、性能等問
    的頭像 發(fā)表于 03-13 15:12 ?314次閱讀
    鴻蒙開發(fā)實戰(zhàn):【性能<b class='flag-5'>調(diào)</b><b class='flag-5'>優(yōu)</b>組件】

    jvm調(diào)優(yōu)工具有哪些

    JVM調(diào)優(yōu)是提高Java應(yīng)用程序性能的重要手段,而JVM調(diào)優(yōu)工具則是輔助開發(fā)人員進(jìn)行調(diào)優(yōu)工作的利
    的頭像 發(fā)表于 12-05 11:44 ?923次閱讀

    jvm調(diào)優(yōu)主要是調(diào)哪里

    JVM調(diào)優(yōu)主要涉及內(nèi)存管理、垃圾回收、線程管理與鎖優(yōu)化等方面。下面將詳細(xì)介紹每個方面的調(diào)優(yōu)技術(shù)和策略以及如何進(jìn)行優(yōu)化。 內(nèi)存管理 JVM的內(nèi)存管理主要包括堆內(nèi)存、棧內(nèi)存和非堆內(nèi)存。堆內(nèi)
    的頭像 發(fā)表于 12-05 11:37 ?1335次閱讀

    jvm參數(shù)的設(shè)置和jvm調(diào)優(yōu)

    JVM(Java虛擬機(jī))參數(shù)的設(shè)置和調(diào)優(yōu)對于提高Java應(yīng)用程序的性能和穩(wěn)定性非常重要。在本文中,我們將詳細(xì)介紹JVM參數(shù)的設(shè)置和調(diào)優(yōu)方法。 一、JVM參數(shù)的設(shè)置 內(nèi)存參數(shù): -Xms
    的頭像 發(fā)表于 12-05 11:36 ?1067次閱讀

    jvm調(diào)優(yōu)參數(shù)

    JVM(Java虛擬機(jī))是Java程序的運(yùn)行環(huán)境,它負(fù)責(zé)解釋Java字節(jié)碼并執(zhí)行相應(yīng)的指令。為了提高應(yīng)用程序的性能和穩(wěn)定性,我們可以調(diào)優(yōu)JVM的參數(shù)。 JVM調(diào)優(yōu)主要涉及到堆內(nèi)存、垃圾
    的頭像 發(fā)表于 12-05 11:29 ?524次閱讀

    什么場景需要jvm調(diào)優(yōu)

    JVM調(diào)優(yōu)是指對Java虛擬機(jī)進(jìn)行性能優(yōu)化和資源管理,以提高應(yīng)用程序的運(yùn)行效率和吞吐量。JVM調(diào)優(yōu)的場景有很多,下面將詳細(xì)介紹各種不同的場景。 高并發(fā)場景:在高并發(fā)場景下,系統(tǒng)需要處理
    的頭像 發(fā)表于 12-05 11:14 ?1091次閱讀

    javajvm調(diào)優(yōu)有幾種方法

    JVM調(diào)優(yōu)是Java應(yīng)用程序性能優(yōu)化過程中的重要步驟,它通過針對JVM進(jìn)行優(yōu)化來提高應(yīng)用程序的性能和可靠性。JVM調(diào)優(yōu)可以根據(jù)具體的場景和需求,采用不同的方法和策略進(jìn)行。 首先,我們需
    的頭像 發(fā)表于 12-05 11:11 ?1854次閱讀

    電氣人的20道變頻器知識(下)

    電氣人的20道變頻器知識(下)
    的頭像 發(fā)表于 10-16 09:06 ?403次閱讀

    電氣人的20道變頻器知識(上)

    電氣人的20道變頻器知識(上)
    的頭像 發(fā)表于 10-11 14:30 ?360次閱讀