hive的sql的執行計劃。
最近碰到有人問我,一個hql當中,如果有一個join,然後 有一個group by 操作。這個時候的map有多少個;
其實之前也看執行計劃。今天有空就研究了一下,一看這裏面的學問還真的不少。下面就以一個例子來說明:
explain select s0.sno,count(distinct s0.sname) from student s0 left outer join student1 s1 on (s0.sno=s1.sno) group by s0.sno;
這裏有兩張表,一個student表,一個student1表。兩個表的sno,做一個join操作。並且對 sno進行分組,然後將分組完成之後的表達式中的sname不同的條數統計出來。
下面我們執行這個解釋語句,執行的結果如下:
STAGE DEPENDENCIES:
Stage-5 is a root stage
Stage-2 depends on stages: Stage-5
Stage-0 depends on stages: Stage-2
--這裏將整個的語句劃分為三個階段,Stage-5作為根目錄,然後Stage-2是對Stage-5的依賴。最後Stage-0將結果顯示出來
STAGE PLANS:
Stage: Stage-5
Map Reduce Local Work
Alias -> Map Local Tables:
s1 --這裏先進行第一次的map,然後這裏將第二張表的表名加載進來,標記別名。這裏進行的Fetch 操作。
Fetch Operator
limit: -1
Alias -> Map Local Operator Tree: --這裏是本地的map 操作加載數據。
s1
TableScan
alias: s1
Statistics: Num rows: 40 Data size: 160 Basic stats: COMPLETE Column stats: NONE
HashTable Sink Operator --這裏進行的hash操作。下面是條件表達式。
condition expressions:
0 {sno} {sname}
1
keys:
0 sno (type: int)
1 sno (type: int)
Stage: Stage-2 --然後進入到第二階段。在這個階段才是真正的map reduce階段。
Map Reduce
Map Operator Tree: --這裏進行的map操作。
TableScan --首先掃描坐標的表。
alias: s0
Statistics: Num rows: 3 Data size: 320 Basic stats: COMPLETE Column stats: NONE
Map Join Operator --這裏采用的hive吧這條sql解釋為了map join。
condition map:
Left Outer Join0 to 1 --這裏進行連接。將左表和右表進行連接。
condition expressions:
0 {sno} {sname}
1
keys:
0 sno (type: int)
1 sno (type: int)
outputColumnNames: _col0, _col1 --這裏輸出兩列。分別是sno,sname。
Statistics: Num rows: 44 Data size: 176 Basic stats: COMPLETE Column stats: NONE
Select Operator --在這裏執行了一次select操作。
expressions: _col0 (type: int), _col1 (type: string)
outputColumnNames: _col0, _col1
Statistics: Num rows: 44 Data size: 176 Basic stats: COMPLETE Column stats: NONE
Group By Operator --在hive當中,為了優化sql,在數據進入到reduce端之前,會對數據進行簡單的分組。在這裏將分組的sno和sname,作為健,輸出的三個列的數據。
aggregations: count(DISTINCT _col1)
keys: _col0 (type: int), _col1 (type: string)
mode: hash
outputColumnNames: _col0, _col1, _col2 --這裏進行三個列的輸出對於這 _col2,我的理解是兩個列組成的和。
Statistics: Num rows: 44 Data size: 176 Basic stats: COMPLETE Column stats: NONE
Reduce Output Operator --在這裏我們可以看到在進入到reduce之前,需要進行一些操作。
key expressions: _col0 (type: int), _col1 (type: string)
sort order: ++ --這裏對數據進行分組排序,也是shuffle過程的前期準備。對同一個map task端的數據進行排序。
Map-reduce partition columns: _col0 (type: int) --這裏將對map出的數據進行分組,這裏是將數據按照group by的列名稱進行分作輸送到不同的partition當中。
Statistics: Num rows: 44 Data size: 176 Basic stats: COMPLETE Column stats: NONE
Local Work:
Map Reduce Local Work
Reduce Operator Tree: --在這裏我們的數據進入到reduce階段的處理。
Group By Operator --在這裏才是正真的分組。
aggregations: count(DISTINCT KEY._col1:0._col0) --然後我們將各個組當中的數據按照我們分好的組,然後統計這個組當中不同的sname的數量。
keys: KEY._col0 (type: int)
mode: mergepartial
outputColumnNames: _col0, _col1 --這裏將統計的好書進行輸出。
Statistics: Num rows: 22 Data size: 88 Basic stats: COMPLETE Column stats: NONE
Select Operator
expressions: _col0 (type: int), _col1 (type: bigint)
outputColumnNames: _col0, _col1
Statistics: Num rows: 22 Data size: 88 Basic stats: COMPLETE Column stats: NONE
File Output Operator --這裏是文件的數據操作,也是落地到磁盤的操作。
compressed: false
Statistics: Num rows: 22 Data size: 88 Basic stats: COMPLETE Column stats: NONE
table:
input format: org.apache.hadoop.mapred.TextInputFormat --這個是讀入數據的操作。
output format: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat --這個是輸出數據的格式。
serde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe
Stage: Stage-0 --在這個階段我們對剛才處理的數據進行展示處理。
Fetch Operator
limit: -1
Processor Tree:
ListSink
其實這裏我們看到數據寫磁盤的操作。在map完了之後的階段。可能是因為數據量不夠大的緣故吧。
另外這裏采用的是map jion的操作也沒有看到在join的時候,出現shuffle的過程。我覺得可能也是數據量太小了吧。直接加載進了分布式緩存當中。才造成現在的現象。
如果有解釋不對的地方,如果有人看到麻煩指點。
hive的sql的執行計劃。