hive sql編譯過程

sql查詢語句處理步驟流程圖sql

準備實例,建立表,插入數據,寫要分析的實例查詢語句
1.首先建立兩個表優化

2.建立兩個表,並插入表數據,腳本略
3.編寫我們要解析的查詢語句,即本篇要查詢的實例語句。ui

select top(4)  status , max(m.id) as maxMemberID
from [dbo].[Member] as m right outer join [dbo].[Order] as o 
(on m.id=o.member_id 
where m.id>0)
group by status 
having status>=0
order by maxMemberID asc

實例語句分步驟分析
1.從from開始
1.1 加載左表翻譯

from [dbo].[Member] as m

查詢結果:member表中的全部數據
1.2 這裏應該是 right outer join ,可是這裏在sql中被定義分解爲2個步驟,即join ,right outer join 。表達式關鍵字從左到右,依次執行code

join [dbo].[Order] as o

查詢結果:存入虛擬表vt1,爲兩個表的笛卡爾集合。
1.三、on 篩選器排序

on m.id=o.member_id

查詢結果以下: 內存

右表(order)做爲保留表,把剩餘的數據從新添加到上一步的虛擬表vt2中,生成虛擬表vt3。
2. where 階段ci

where m.id>0

查詢結果:存入虛擬表vt4,爲篩選的條件爲true的結果集,這裏加入一個記憶點,就是,where的篩選刪除爲永久的,而on的篩選刪除爲暫時的,由於on篩選事後,有可能會通過outer添加外部行,從新把數據加載回來,而where則不能。
3.group by分組it

group by status

查詢結果:存入vt5,以status列的數值開始分組,即status列,值同樣的分爲一組,這裏的兩個null在三值邏輯中被視爲true。三值邏輯:true,false,null。此三值,null爲未知,是數據的邏輯特點,有的地方兩個null相等爲ture,在有些地方則爲false。這個你百度下看看有不少講解。
4.having 篩選編譯

having status>=0

查詢結果:篩選分好組的組數據,把不知足條件的刪除掉
5.select 查詢挑揀計算列
5.一、計算表達式

select status , max(m.id)

5.二、distinct過濾重複 
5.三、top 結合order by 篩選 多少行,但這裏的數據沒有排序只是把多少行數據列出來而已。
6.order by
排序顯示

Join的實現原理

select u.name, o.orderid from order o join user u on o.uid = u.uid;

在map的輸出value中爲不一樣表的數據打上tag標記,在reduce階段根據tag判斷數據來源。MapReduce的過程以下(這裏只是說明最基本的Join的實現,還有其餘的實現方式)

Group By的實現原理

select rank, isonline, count(*) from city group by rank, isonline;

將GroupBy的字段組合爲map的輸出key值,利用MapReduce的排序,在reduce階段保存LastKey區分不一樣的key。MapReduce的過程以下(固然這裏只是說明Reduce端的非Hash聚合過程)

Distinct的實現原理

select dealid, count(distinct uid) num from order group by dealid;

當只有一個distinct字段時,若是不考慮Map階段的Hash GroupBy,只須要將GroupBy字段和Distinct字段組合爲map輸出key,利用mapreduce的排序,同時將GroupBy字段做爲reduce的key,在reduce階段保存LastKey便可完成去重

若是有多個distinct字段呢,以下面的SQL

select dealid, count(distinct uid), count(distinct date) from order group by dealid;

實現方式有兩種:
(1)若是仍然按照上面一個distinct字段的方法,即下圖這種實現方式,沒法跟據uid和date分別排序,也就沒法經過LastKey去重,仍然須要在reduce階段在內存中經過Hash去重

(2)第二種實現方式,能夠對全部的distinct字段編號,每行數據生成n行數據,那麼相同字段就會分別排序,這時只須要在reduce階段記錄LastKey便可去重。
這種實現方式很好的利用了MapReduce的排序,節省了reduce階段去重的內存消耗,可是缺點是增長了shuffle的數據量。
須要注意的是,在生成reduce value時,除第一個distinct字段所在行須要保留value值,其他distinct數據行value字段都可爲空。

SQL轉化爲MapReduce的過程
瞭解了MapReduce實現SQL基本操做以後,咱們來看看Hive是如何將SQL轉化爲MapReduce任務的,整個編譯過程分爲六個階段:

Antlr定義SQL的語法規則,完成SQL詞法,語法解析,將SQL轉化爲抽象語法樹AST Tree 遍歷AST Tree,抽象出查詢的基本組成單元QueryBlock 遍歷QueryBlock,翻譯爲執行操做樹OperatorTree 邏輯層優化器進行OperatorTree變換,合併沒必要要的ReduceSinkOperator,減小shuffle數據量 遍歷OperatorTree,翻譯爲MapReduce任務 物理層優化器進行MapReduce任務的變換,生成最終的執行計劃

相關文章
相關標籤/搜索