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

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

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

如何通過explain來驗證sql的執(zhí)行順序

Linux愛好者 ? 來源:五分鐘學大數(shù)據(jù) ? 作者:園陌 ? 2021-09-07 16:24 ? 次閱讀

關于 sql 語句的執(zhí)行順序網(wǎng)上有很多資料,但是大多都沒進行驗證,并且很多都有點小錯誤,尤其是對于 select 和 group by 執(zhí)行的先后順序,有說 select 先執(zhí)行,有說 group by 先執(zhí)行,到底它倆誰先執(zhí)行呢?

今天我們通過 explain 來驗證下 sql 的執(zhí)行順序。

在驗證之前,先說結論,Hive 中 sql 語句的執(zhí)行順序如下:

from 。. where 。. join 。. on 。. select 。. group by 。. select 。. having 。. distinct 。. order by 。. limit 。. union/union all

可以看到 group by 是在兩個 select 之間,我們知道 Hive 是默認開啟 map 端的 group by 分組的,所以在 map 端是 select 先執(zhí)行,在 reduce 端是 group by先執(zhí)行。

下面我們通過一個 sql 語句分析下:

select

sum(b.order_amount) sum_amount,

count(a.userkey) count_user

from user_info a

left join user_order b

on a.idno=b.idno

where a.idno 》 ‘112233’group by a.idno

having count_user》1limit 10;

上面這條 sql 語句是可以成功執(zhí)行的,我們看下它在 MR 中的執(zhí)行順序:

Map 階段:

執(zhí)行 from,進行表的查找與加載;

執(zhí)行 where,注意:sql 語句中 left join 寫在 where 之前的,但是實際執(zhí)行先執(zhí)行 where 操作,因為 Hive 會對語句進行優(yōu)化,如果符合謂詞下推規(guī)則,將進行謂詞下推;

執(zhí)行 left join 操作,按照 key 進行表的關聯(lián);

執(zhí)行輸出列的操作,注意: select 后面只有兩個字段(order_amount,userkey),此時 Hive 是否只輸出這兩個字段呢,當然不是,因為 group by 的是 idno,如果只輸出 select 的兩個字段,后面 group by 將沒有辦法對 idno 進行分組,所以此時輸出的字段有三個:idno,order_amount,userkey;

執(zhí)行 map 端的 group by,此時的分組方式采用的是哈希分組,按照 idno 分組,進行order_amount 的 sum 操作和 userkey 的 count 操作,最后按照 idno 進行排序(group by 默認會附帶排序操作);

Reduce 階段:

執(zhí)行 reduce 端的 group by,此時的分組方式采用的是合并分組,對 map 端發(fā)來的數(shù)據(jù)按照 idno 進行分組合并,同時進行聚合操作 sum(order_amount)和 count(userkey);

執(zhí)行 select,此時輸出的就只有 select 的兩個字段:sum(order_amount) as sum_amount,count(userkey) as count_user;

執(zhí)行 having,此時才開始執(zhí)行 group by 后的 having 操作,對 count_user 進行過濾,注意:因為上一步輸出的只有 select 的兩個字段了,所以 having 的過濾字段只能是這兩個字段;

執(zhí)行 limit,限制輸出的行數(shù)為 10。

上面這個執(zhí)行順序到底對不對呢,我們可以通過 explain 執(zhí)行計劃來看下,內(nèi)容過多,我們分階段來看。

首先看下 sql 語句的執(zhí)行依賴:

b87621aa-0fb2-11ec-8fb8-12bb97331649.png

我們看到 Stage-5 是根,也就是最先執(zhí)行 Stage-5,Stage-2 依賴 Stage-5,Stage-0 依賴 Stage-2。

首先執(zhí)行 Stage-5:

b883ad3e-0fb2-11ec-8fb8-12bb97331649.png

圖中標 ① 處是表掃描操作,注意先掃描的 b 表,也就是 left join 后面的表,然后進行過濾操作(圖中標 ② 處),我們 sql 語句中是對 a 表進行的過濾,但是 Hive 也會自動對 b 表進行相同的過濾操作,這樣可以減少關聯(lián)的數(shù)據(jù)量。

接下來執(zhí)行 Stage-2:

首先是 Map 端操作:

b894d690-0fb2-11ec-8fb8-12bb97331649.png

先掃描 a 表(圖中標 ① 處);接下來進行過濾操作 idno 》 ‘112233’(圖中標 ② 處);然后進行 left join,關聯(lián)的 key 是 idno(圖中標 ③ 處);執(zhí)行完關聯(lián)操作之后會進行輸出操作,輸出的是三個字段,包括 select 的兩個字段加 group by 的一個字段(圖中標 ④ 處);然后進行 group by 操作,分組方式是 hash(圖中標 ⑤ 處);然后進行排序操作,按照 idno 進行正向排序(圖中標 ⑥ 處)。

然后是 Reduce 端操作:

b8a76c38-0fb2-11ec-8fb8-12bb97331649.png

首先進行 group by 操作,注意此時的分組方式是 mergepartial 合并分組(圖中標 ① 處);然后進行 select 操作,此時輸出的字段只有兩個了,輸出的行數(shù)是 30304 行(圖中標 ② 處);接下來執(zhí)行 having 的過濾操作,過濾出 count_user》1 的字段,輸出的行數(shù)是 10101 行(圖中標 ③ 處);然后進行 limit 限制輸出的行數(shù)(圖中標 ④ 處);圖中標 ⑤ 處表示是否對文件壓縮,false 不壓縮。

執(zhí)行計劃中的數(shù)據(jù)量只是預測的數(shù)據(jù)量,不是真實運行的,所以數(shù)據(jù)可能不準!

最后是 Stage-0 階段:

b8d9f658-0fb2-11ec-8fb8-12bb97331649.png

限制最終輸出的行數(shù)為 10 行。

總結

通過上面對 SQL 執(zhí)行計劃的分析,總結以下幾點:

每個 stage 都是一個獨立的 MR,復雜的 hive sql 語句可以產(chǎn)生多個 stage,可以通過執(zhí)行計劃的描述,看看具體步驟是什么。

對于 group by 的 key,必須是表中的字段,對于 having 的 key,必須是 select 的字段。

order by 是在 select 后執(zhí)行的,所以 order by 的 key 必須是 select 的字段。

select 最好指明字段,select * 會增加很多不必要的消耗(CPU、IO、內(nèi)存、網(wǎng)絡帶寬)。

責任編輯:haq

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

    關注

    1

    文章

    772

    瀏覽量

    44205
  • 數(shù)據(jù)庫

    關注

    7

    文章

    3842

    瀏覽量

    64569

原文標題:Hive SQL 語句的正確執(zhí)行順序

文章出處:【微信號:LinuxHub,微信公眾號:Linux愛好者】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    Devart: dbForge Compare Bundle for SQL Server—比較SQL數(shù)據(jù)庫最簡單、最準確的方法

    、備份和腳本文件夾中的數(shù)據(jù)差異。它可以同步任意數(shù)量數(shù)據(jù)庫中的數(shù)據(jù),只需點擊幾下即可恢復損壞或丟失的數(shù)據(jù)。 dbForge模式比較 幫助比較數(shù)據(jù)庫模式,分析差異,并通過SQL腳本同步差異。它適用于所有
    的頭像 發(fā)表于 01-17 11:35 ?87次閱讀

    通過Skyvia Connect SQL終端節(jié)點訪問任何數(shù)據(jù)

    通過 Skyvia Connect SQL 終端節(jié)點訪問任何數(shù)據(jù) ? 通過 Skyvia Connect SQL 終端節(jié)點訪問任何數(shù)據(jù)ADO.NET 數(shù)據(jù)網(wǎng)關 使用 Skyvia Co
    的頭像 發(fā)表于 01-02 09:31 ?99次閱讀
    <b class='flag-5'>通過</b>Skyvia Connect <b class='flag-5'>SQL</b>終端節(jié)點訪問任何數(shù)據(jù)

    淺談SQL優(yōu)化小技巧

    存儲在緩存中的數(shù)據(jù); (3)未命中緩存后,MySQL通過關鍵字將SQL語句進行解析,并生成一顆對應的解析樹,MySQL解析器將使用MySQL語法進行驗證和解析。 例如,驗證是否使用了錯
    的頭像 發(fā)表于 12-25 09:59 ?529次閱讀

    常用SQL函數(shù)及其用法

    SQL 函數(shù)及其用法: 一、聚合函數(shù)(Aggregate Functions) 聚合函數(shù)對一組值執(zhí)行計算,并返回單個值。 COUNT() 用途 :返回匹配指定條件的行數(shù)。 示例 : SELECT
    的頭像 發(fā)表于 11-19 10:18 ?381次閱讀

    SQL與NoSQL的區(qū)別

    景。 SQL數(shù)據(jù)庫 SQL數(shù)據(jù)庫,也稱為關系型數(shù)據(jù)庫管理系統(tǒng)(RDBMS),是一種基于關系模型的數(shù)據(jù)庫。它使用表格、行和列組織數(shù)據(jù),并通過SQL
    的頭像 發(fā)表于 11-19 10:15 ?209次閱讀

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

    不盡人意。本文針對Hive SQL的性能優(yōu)化進行深入研究,提出了一系列可行的調(diào)優(yōu)方案,并給出了相應的優(yōu)化案例和優(yōu)化前后的SQL代碼。通過合理的優(yōu)化策略和技巧,能夠顯著提升Hive SQL
    的頭像 發(fā)表于 09-24 13:30 ?302次閱讀

    IP 地址在 SQL 注入攻擊中的作用及防范策略

    SQL 注入是通過將惡意的 SQL 代碼插入到輸入?yún)?shù)中,欺騙應用程序執(zhí)行這些惡意代碼,從而實現(xiàn)對數(shù)據(jù)庫的非法操作。例如,在一個登錄表單中,如果輸入的用戶名被直接拼接到
    的頭像 發(fā)表于 08-05 17:36 ?349次閱讀

    如何在SQL中創(chuàng)建觸發(fā)器

    SQL中,觸發(fā)器(Trigger)是一種特殊類型的存儲過程,它自動執(zhí)行或激活響應表上的數(shù)據(jù)修改事件(如INSERT、UPDATE、DELETE等)。觸發(fā)器可以用于維護數(shù)據(jù)庫的完整性、自動化復雜
    的頭像 發(fā)表于 07-18 16:01 ?2069次閱讀

    什么是 Flink SQL 解決不了的問題?

    簡介 在實時數(shù)據(jù)開發(fā)過程中,大家經(jīng)常會用 Flink SQL 或者 Flink DataStream API 做數(shù)據(jù)加工。通常情況下選用2者都能加工出想要的數(shù)據(jù),但是總會有 Flink SQL
    的頭像 發(fā)表于 07-09 20:50 ?355次閱讀

    PLC順序啟動逆順序停止電路如何運行

    了解了順序啟動電路,今天再來看看順序啟動逆順序停止電路如何運行。
    發(fā)表于 04-09 14:13 ?830次閱讀
    PLC<b class='flag-5'>順序</b>啟動逆<b class='flag-5'>順序</b>停止電路如何運行

    為什么需要監(jiān)控SQL服務器?

    服務器是存儲、處理和管理數(shù)據(jù)的關系數(shù)據(jù)庫管理系統(tǒng) (RDBMS) 工具或軟件,例如Microsoft的MSSQL、Oracle DB和PostgreSQL。此外,服務器執(zhí)行SQL查詢和命令操作關系數(shù)據(jù)庫。實際上,
    的頭像 發(fā)表于 02-19 17:19 ?503次閱讀

    plc梯形圖順序執(zhí)行的原則是什么

    PLC(可編程邏輯控制器)梯形圖(或稱為梯形邏輯圖)是用于描述和編程PLC的一種常用圖形化編程語言。它采用了一種順序執(zhí)行的原則,即按照圖中元素的排列順序從左到右、從上到下依次執(zhí)行。 梯
    的頭像 發(fā)表于 02-05 11:13 ?4796次閱讀

    觸發(fā)器的觸發(fā)順序是什么

    不同類型的觸發(fā)器可能有不同的執(zhí)行順序。例如,對于同一個表上的多個觸發(fā)器,插入觸發(fā)器(INSERT trigger)可能先于更新觸發(fā)器(UPDATE trigger)執(zhí)行
    的頭像 發(fā)表于 02-05 10:09 ?1203次閱讀
    觸發(fā)器的觸發(fā)<b class='flag-5'>順序</b>是什么

    如何用Rust過程宏魔法簡化SQL函數(shù)呢?

    這是 RisingWave 中一個 SQL 函數(shù)的實現(xiàn)。只需短短幾行代碼,通過在 Rust 函數(shù)上加一行過程宏,我們就把它包裝成了一個 SQL 函數(shù)。
    的頭像 發(fā)表于 01-23 09:43 ?1029次閱讀
    如何用Rust過程宏魔法簡化<b class='flag-5'>SQL</b>函數(shù)呢?

    查詢SQL在mysql內(nèi)部是如何執(zhí)行?

    我們知道在mySQL客戶端,輸入一條查詢SQL,然后看到返回查詢的結果。這條查詢語句在 MySQL 內(nèi)部到底是如何執(zhí)行的呢?本文跟大家探討一下哈,我們先來看下MySQL基本架構~
    的頭像 發(fā)表于 01-22 14:53 ?605次閱讀
    查詢<b class='flag-5'>SQL</b>在mysql內(nèi)部是如何<b class='flag-5'>執(zhí)行</b>?