Hive底層原理:explain執(zhí)行計劃詳解

不懂hive中的explain,說明hive還沒入門匀借,學(xué)會explain碴倾,能夠給我們工作中使用hive帶來極大的便利逗噩!【要源碼請SI`XIN】【不想排版,不想排版跌榔,不想排版】

理論
本節(jié)將介紹 explain 的用法及參數(shù)介紹
HIVE提供了EXPLAIN命令來展示一個查詢的執(zhí)行計劃,這個執(zhí)行計劃對于我們了解底層原理异雁,hive 調(diào)優(yōu),排查數(shù)據(jù)傾斜等很有幫助

使用語法如下:

EXPLAIN [EXTENDED|CBO|AST|DEPENDENCY|AUTHORIZATION|LOCKS|VECTORIZATION|ANALYZE] query
explain 后面可以跟以下可選參數(shù)僧须,注意:這幾個可選參數(shù)不是 hive 每個版本都支持的

EXTENDED:加上 extended 可以輸出有關(guān)計劃的額外信息纲刀。這通常是物理信息,例如文件名担平。這些額外信息對我們用處不大
CBO:輸出由Calcite優(yōu)化器生成的計劃示绊。CBO 從 hive 4.0.0 版本開始支持
AST:輸出查詢的抽象語法樹。AST 在hive 2.1.0 版本刪除了暂论,存在bug面褐,轉(zhuǎn)儲AST可能會導(dǎo)致OOM錯誤,將在4.0.0版本修復(fù)
DEPENDENCY:dependency在EXPLAIN語句中使用會產(chǎn)生有關(guān)計劃中輸入的額外信息取胎。它顯示了輸入的各種屬性
AUTHORIZATION:顯示所有的實體需要被授權(quán)執(zhí)行(如果存在)的查詢和授權(quán)失敗
LOCKS:這對于了解系統(tǒng)將獲得哪些鎖以運(yùn)行指定的查詢很有用展哭。LOCKS 從 hive 3.2.0 開始支持
VECTORIZATION:將詳細(xì)信息添加到EXPLAIN輸出中,以顯示為什么未對Map和Reduce進(jìn)行矢量化闻蛀。從 Hive 2.3.0 開始支持
ANALYZE:用實際的行數(shù)注釋計劃匪傍。從 Hive 2.2.0 開始支持
在 hive cli 中輸入以下命令(hive 2.3.7):

explain select sum(id) from test1;
得到結(jié)果(請逐行看完,即使看不懂也要每行都看):

STAGE DEPENDENCIES:
Stage-1 is a root stage
Stage-0 depends on stages: Stage-1

STAGE PLANS:
Stage: Stage-1
Map Reduce
Map Operator Tree:
TableScan
alias: test1
Statistics: Num rows: 6 Data size: 75 Basic stats: COMPLETE Column stats: NONE
Select Operator
expressions: id (type: int)
outputColumnNames: id
Statistics: Num rows: 6 Data size: 75 Basic stats: COMPLETE Column stats: NONE
Group By Operator
aggregations: sum(id)
mode: hash
outputColumnNames: _col0
Statistics: Num rows: 1 Data size: 8 Basic stats: COMPLETE Column stats: NONE
Reduce Output Operator
sort order:
Statistics: Num rows: 1 Data size: 8 Basic stats: COMPLETE Column stats: NONE
value expressions: _col0 (type: bigint)
Reduce Operator Tree:
Group By Operator
aggregations: sum(VALUE._col0)
mode: mergepartial
outputColumnNames: _col0
Statistics: Num rows: 1 Data size: 8 Basic stats: COMPLETE Column stats: NONE
File Output Operator
compressed: false
Statistics: Num rows: 1 Data size: 8 Basic stats: COMPLETE Column stats: NONE
table:
input format: org.apache.hadoop.mapred.SequenceFileInputFormat
output format: org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat
serde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe

Stage: Stage-0
Fetch Operator
limit: -1
Processor Tree:
ListSink
看完以上內(nèi)容有什么感受觉痛,是不是感覺都看不懂役衡,不要著急,下面將會詳細(xì)講解每個參數(shù)秧饮,相信你學(xué)完下面的內(nèi)容之后再看 explain 的查詢結(jié)果將游刃有余映挂。

一個HIVE查詢被轉(zhuǎn)換為一個由一個或多個stage組成的序列(有向無環(huán)圖DAG)泽篮。這些stage可以是MapReduce stage,也可以是負(fù)責(zé)元數(shù)據(jù)存儲的stage柑船,也可以是負(fù)責(zé)文件系統(tǒng)的操作(比如移動和重命名)的stage帽撑。
我們將上述結(jié)果拆分看,先從最外層開始鞍时,包含兩個大的部分:

stage dependencies: 各個stage之間的依賴性
stage plan: 各個stage的執(zhí)行計劃
先看第一部分 stage dependencies 亏拉,包含兩個 stage,Stage-1 是根stage逆巍,說明這是開始的stage及塘,Stage-0 依賴 Stage-1,Stage-1執(zhí)行完成后執(zhí)行Stage-0锐极。

再看第二部分 stage plan笙僚,里面有一個 Map Reduce,一個MR的執(zhí)行計劃分為兩個部分:

Map Operator Tree: MAP端的執(zhí)行計劃樹
Reduce Operator Tree: Reduce端的執(zhí)行計劃樹
這兩個執(zhí)行計劃樹里面包含這條sql語句的 operator:

map端第一個操作肯定是加載表灵再,所以就是 TableScan 表掃描操作肋层,常見的屬性:
alias: 表名稱
Statistics: 表統(tǒng)計信息,包含表中數(shù)據(jù)條數(shù)翎迁,數(shù)據(jù)大小等
Select Operator: 選取操作栋猖,常見的屬性 :

expressions:需要的字段名稱及字段類型
outputColumnNames:輸出的列名稱
Statistics:表統(tǒng)計信息,包含表中數(shù)據(jù)條數(shù)汪榔,數(shù)據(jù)大小等
Group By Operator:分組聚合操作蒲拉,常見的屬性:

aggregations:顯示聚合函數(shù)信息
mode:聚合模式,值有 hash:隨機(jī)聚合痴腌,就是hash partition雌团;partial:局部聚合;final:最終聚合
keys:分組的字段衷掷,如果沒有分組辱姨,則沒有此字段
outputColumnNames:聚合之后輸出列名
Statistics: 表統(tǒng)計信息,包含分組聚合之后的數(shù)據(jù)條數(shù)戚嗅,數(shù)據(jù)大小等
Reduce Output Operator:輸出到reduce操作雨涛,常見屬性:

sort order:值為空 不排序;值為 + 正序排序懦胞,值為 - 倒序排序替久;值為 +- 排序的列為兩列,第一列為正序躏尉,第二列為倒序
Filter Operator:過濾操作蚯根,常見的屬性:

predicate:過濾條件,如sql語句中的where id>=1,則此處顯示(id >= 1)
Map Join Operator:join 操作颅拦,常見的屬性:

condition map:join方式 蒂誉,如Inner Join 0 to 1 Left Outer Join0 to 2
keys: join 的條件字段
outputColumnNames: join 完成之后輸出的字段
Statistics: join 完成之后生成的數(shù)據(jù)條數(shù),大小等
File Output Operator:文件輸出操作距帅,常見的屬性

compressed:是否壓縮
table:表的信息右锨,包含輸入輸出文件格式化方式,序列化方式等
Fetch Operator 客戶端獲取數(shù)據(jù)操作碌秸,常見的屬性:

limit绍移,值為 -1 表示不限制條數(shù),其他值為限制的條數(shù)
好讥电,學(xué)到這里再翻到上面 explain 的查詢結(jié)果蹂窖,是不是感覺基本都能看懂了。

實踐
本節(jié)介紹 explain 能夠為我們在生產(chǎn)實踐中帶來哪些便利及解決我們哪些迷惑

  1. join 語句會過濾 null 的值嗎恩敌?
    現(xiàn)在瞬测,我們在hive cli 輸入以下查詢計劃語句

select a.id,b.user_name from test1 a join test2 b on a.id=b.id;
問:上面這條 join 語句會過濾 id 為 null 的值嗎

執(zhí)行下面語句:

explain select a.id,b.user_name from test1 a join test2 b on a.id=b.id;
我們來看結(jié)果 (為了適應(yīng)頁面展示,僅截取了部分輸出信息):

TableScan
alias: a
Statistics: Num rows: 6 Data size: 75 Basic stats: COMPLETE Column stats: NONE
Filter Operator
predicate: id is not null (type: boolean)
Statistics: Num rows: 6 Data size: 75 Basic stats: COMPLETE Column stats: NONE
Select Operator
expressions: id (type: int)
outputColumnNames: _col0
Statistics: Num rows: 6 Data size: 75 Basic stats: COMPLETE Column stats: NONE
HashTable Sink Operator
keys:
0 _col0 (type: int)
1 _col0 (type: int)
...
從上述結(jié)果可以看到 predicate: id is not null 這樣一行纠炮,說明 join 時會自動過濾掉關(guān)聯(lián)字段為 null 值的情況涣楷,但 left join 或 full join 是不會自動過濾的,大家可以自行嘗試下抗碰。

  1. group by 分組語句會進(jìn)行排序嗎?
    看下面這條sql

select id,max(user_name) from test1 group by id;
問:group by 分組語句會進(jìn)行排序嗎

直接來看 explain 之后結(jié)果 (為了適應(yīng)頁面展示绽乔,僅截取了部分輸出信息)

TableScan
alias: test1
Statistics: Num rows: 9 Data size: 108 Basic stats: COMPLETE Column stats: NONE
Select Operator
expressions: id (type: int), user_name (type: string)
outputColumnNames: id, user_name
Statistics: Num rows: 9 Data size: 108 Basic stats: COMPLETE Column stats: NONE
Group By Operator
aggregations: max(user_name)
keys: id (type: int)
mode: hash
outputColumnNames: _col0, _col1
Statistics: Num rows: 9 Data size: 108 Basic stats: COMPLETE Column stats: NONE
Reduce Output Operator
key expressions: _col0 (type: int)
sort order: +
Map-reduce partition columns: _col0 (type: int)
Statistics: Num rows: 9 Data size: 108 Basic stats: COMPLETE Column stats: NONE
value expressions: _col1 (type: string)
...
我們看 Group By Operator弧蝇,里面有 keys: id (type: int) 說明按照 id 進(jìn)行分組的,再往下看還有 sort order: + 折砸,說明是按照 id 字段進(jìn)行正序排序的看疗。

  1. 哪條sql執(zhí)行效率高呢?
    觀察兩條sql語句

SELECT
a.id,
b.user_name
FROM
test1 a
JOIN test2 b ON a.id = b.id
WHERE
a.id > 2;
SELECT
a.id,
b.user_name
FROM
(SELECT * FROM test1 WHERE id > 2) a
JOIN test2 b ON a.id = b.id;
這兩條sql語句輸出的結(jié)果是一樣的睦授,但是哪條sql執(zhí)行效率高呢
有人說第一條sql執(zhí)行效率高两芳,因為第二條sql有子查詢,子查詢會影響性能
有人說第二條sql執(zhí)行效率高去枷,因為先過濾之后怖辆,在進(jìn)行join時的條數(shù)減少了,所以執(zhí)行效率就高了

到底哪條sql效率高呢删顶,我們直接在sql語句前面加上 explain竖螃,看下執(zhí)行計劃不就知道了嘛

在第一條sql語句前加上 explain,得到如下結(jié)果

hive (default)> explain select a.id,b.user_name from test1 a join test2 b on a.id=b.id where a.id >2;
OK
Explain
STAGE DEPENDENCIES:
Stage-4 is a root stage
Stage-3 depends on stages: Stage-4
Stage-0 depends on stages: Stage-3

STAGE PLANS:
Stage: Stage-4
Map Reduce Local Work
Alias -> Map Local Tables:
hdt_0:a
Fetch Operator
limit: -1
Alias -> Map Local Operator Tree:
hdt_0:a
TableScan
alias: a
Statistics: Num rows: 6 Data size: 75 Basic stats: COMPLETE Column stats: NONE
Filter Operator
predicate: (id > 2) (type: boolean)
Statistics: Num rows: 2 Data size: 25 Basic stats: COMPLETE Column stats: NONE
Select Operator
expressions: id (type: int)
outputColumnNames: _col0
Statistics: Num rows: 2 Data size: 25 Basic stats: COMPLETE Column stats: NONE
HashTable Sink Operator
keys:
0 _col0 (type: int)
1 _col0 (type: int)

Stage: Stage-3
Map Reduce
Map Operator Tree:
TableScan
alias: b
Statistics: Num rows: 6 Data size: 75 Basic stats: COMPLETE Column stats: NONE
Filter Operator
predicate: (id > 2) (type: boolean)
Statistics: Num rows: 2 Data size: 25 Basic stats: COMPLETE Column stats: NONE
Select Operator
expressions: id (type: int), user_name (type: string)
outputColumnNames: _col0, _col1
Statistics: Num rows: 2 Data size: 25 Basic stats: COMPLETE Column stats: NONE
Map Join Operator
condition map:
Inner Join 0 to 1
keys:
0 _col0 (type: int)
1 _col0 (type: int)
outputColumnNames: _col0, _col2
Statistics: Num rows: 2 Data size: 27 Basic stats: COMPLETE Column stats: NONE
Select Operator
expressions: _col0 (type: int), _col2 (type: string)
outputColumnNames: _col0, _col1
Statistics: Num rows: 2 Data size: 27 Basic stats: COMPLETE Column stats: NONE
File Output Operator
compressed: false
Statistics: Num rows: 2 Data size: 27 Basic stats: COMPLETE Column stats: NONE
table:
input format: org.apache.hadoop.mapred.SequenceFileInputFormat
output format: org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat
serde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe
Local Work:
Map Reduce Local Work

Stage: Stage-0
Fetch Operator
limit: -1
Processor Tree:
ListSink
在第二條sql語句前加上 explain逗余,得到如下結(jié)果

hive (default)> explain select a.id,b.user_name from(select * from test1 where id>2 ) a join test2 b on a.id=b.id;
OK
Explain
STAGE DEPENDENCIES:
Stage-4 is a root stage
Stage-3 depends on stages: Stage-4
Stage-0 depends on stages: Stage-3

STAGE PLANS:
Stage: Stage-4
Map Reduce Local Work
Alias -> Map Local Tables:
hdt_0:test1
Fetch Operator
limit: -1
Alias -> Map Local Operator Tree:
hdt_0:test1
TableScan
alias: test1
Statistics: Num rows: 6 Data size: 75 Basic stats: COMPLETE Column stats: NONE
Filter Operator
predicate: (id > 2) (type: boolean)
Statistics: Num rows: 2 Data size: 25 Basic stats: COMPLETE Column stats: NONE
Select Operator
expressions: id (type: int)
outputColumnNames: _col0
Statistics: Num rows: 2 Data size: 25 Basic stats: COMPLETE Column stats: NONE
HashTable Sink Operator
keys:
0 _col0 (type: int)
1 _col0 (type: int)

Stage: Stage-3
Map Reduce
Map Operator Tree:
TableScan
alias: b
Statistics: Num rows: 6 Data size: 75 Basic stats: COMPLETE Column stats: NONE
Filter Operator
predicate: (id > 2) (type: boolean)
Statistics: Num rows: 2 Data size: 25 Basic stats: COMPLETE Column stats: NONE
Select Operator
expressions: id (type: int), user_name (type: string)
outputColumnNames: _col0, _col1
Statistics: Num rows: 2 Data size: 25 Basic stats: COMPLETE Column stats: NONE
Map Join Operator
condition map:
Inner Join 0 to 1
keys:
0 _col0 (type: int)
1 _col0 (type: int)
outputColumnNames: _col0, _col2
Statistics: Num rows: 2 Data size: 27 Basic stats: COMPLETE Column stats: NONE
Select Operator
expressions: _col0 (type: int), _col2 (type: string)
outputColumnNames: _col0, _col1
Statistics: Num rows: 2 Data size: 27 Basic stats: COMPLETE Column stats: NONE
File Output Operator
compressed: false
Statistics: Num rows: 2 Data size: 27 Basic stats: COMPLETE Column stats: NONE
table:
input format: org.apache.hadoop.mapred.SequenceFileInputFormat
output format: org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat
serde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe
Local Work:
Map Reduce Local Work

Stage: Stage-0
Fetch Operator
limit: -1
Processor Tree:
ListSink
大家有什么發(fā)現(xiàn)特咆,除了表別名不一樣,其他的執(zhí)行計劃完全一樣录粱,都是先進(jìn)行 where 條件過濾腻格,在進(jìn)行 join 條件關(guān)聯(lián)画拾。說明 hive 底層會自動幫我們進(jìn)行優(yōu)化,所以這兩條sql語句執(zhí)行效率是一樣的菜职。

最后
以上僅列舉了3個我們生產(chǎn)中既熟悉又有點迷糊的例子青抛,explain 還有很多其他的用途,如查看stage的依賴情況些楣、排查數(shù)據(jù)傾斜脂凶、hive 調(diào)優(yōu)等,小伙伴們可以自行嘗試愁茁。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蚕钦,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子鹅很,更是在濱河造成了極大的恐慌嘶居,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件促煮,死亡現(xiàn)場離奇詭異邮屁,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)菠齿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進(jìn)店門佑吝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人绳匀,你說我怎么就攤上這事芋忿。” “怎么了疾棵?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵戈钢,是天一觀的道長。 經(jīng)常有香客問我是尔,道長殉了,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任拟枚,我火速辦了婚禮薪铜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘恩溅。我一直安慰自己痕囱,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布暴匠。 她就那樣靜靜地躺著鞍恢,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上帮掉,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天弦悉,我揣著相機(jī)與錄音,去河邊找鬼蟆炊。 笑死稽莉,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的涩搓。 我是一名探鬼主播,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼昧甘,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了充边?” 一聲冷哼從身側(cè)響起庸推,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤浇冰,失蹤者是張志新(化名)和其女友劉穎贬媒,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體肘习,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡际乘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了漂佩。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蚓庭。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖仅仆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情垢袱,我是刑警寧澤墓拜,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站请契,受9級特大地震影響咳榜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜爽锥,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一涌韩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧氯夷,春花似錦臣樱、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽玄捕。三九已至,卻和暖如春棚放,著一層夾襖步出監(jiān)牢的瞬間枚粘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工飘蚯, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留馍迄,地道東北人。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓局骤,卻偏偏與公主長得像攀圈,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子庄涡,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,611評論 2 353

推薦閱讀更多精彩內(nèi)容