色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

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

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

3天內不再提示

深度剖析SQL中的Grouping Sets語句1

jf_78858299 ? 來源:元閏子的邀請 ? 作者:元閏子 ? 2023-05-10 17:44 ? 次閱讀

前言

SQL 中 Group By 語句大家都很熟悉, 根據指定的規則對數據進行分組 ,常常和聚合函數一起使用。

比如,考慮有表 dealer,表中數據如下:

id (Int) city (String) car_model (String) quantity (Int)
100 Fremont Honda Civic 10
100 Fremont Honda Accord 15
100 Fremont Honda CRV 7
200 Dublin Honda Civic 20
200 Dublin Honda Accord 10
200 Dublin Honda CRV 3
300 San Jose Honda Civic 5
300 San Jose Honda Accord 8

如果執行 SQL 語句 SELECT id, sum(quantity) FROM dealer GROUP BY id ORDER BY id,會得到如下結果:

+---+-------------+
| id|sum(quantity)|
+---+-------------+
|100|           32|
|200|           33|
|300|           13|
+---+-------------+

上述 SQL 語句的意思就是對數據按 id 列進行分組,然后在每個分組內對 quantity 列進行求和。

Group By 語句除了上面的簡單用法之外,還有更高級的用法,常見的是 Grouping SetsRollUpCube,它們在 OLAP 時比較常用。其中,RollUpCube 都是以 Grouping Sets 為基礎實現的,因此,弄懂了 Grouping Sets,也就理解了 RollUpCube

本文首先簡單介紹 Grouping Sets 的用法,然后以 Spark SQL 作為切入點,深入解析 Grouping Sets 的實現機制。

Spark SQL 是 Apache Spark 大數據處理框架的一個子模塊,用來處理結構化信息。它可以將 SQL 語句翻譯多個任務在 Spark 集群上執行, 允許用戶直接通過 SQL 來處理數據 ,大大提升了易用性。

Grouping Sets 簡介

Spark SQL 官方文檔中 SQL Syntax 一節對 Grouping Sets 語句的描述如下:

Groups the rows for each grouping set specified after GROUPING SETS. (... 一些舉例) This clause is a shorthand for a UNION ALLwhere each leg of the UNION ALL operator performs aggregation of each grouping set specified in the GROUPING SETS clause. (... 一些舉例)

也即,Grouping Sets 語句的作用是指定幾個 grouping set 作為 Group By 的分組規則,然后再將結果聯合在一起。它的效果和, 先分別對這些 grouping set 進行 Group By 分組之后,再通過 Union All 將結果聯合起來 ,是一樣的。

比如,對于 dealer 表,Group By Grouping Sets ((city, car_model), (city), (car_model), ())Union All((Group By city, car_model), (Group By city), (Group By car_model), 全局聚合) 的效果是相同的:

先看 Grouping Sets 版的執行結果:

spark-sql> SELECT city, car_model, sum(quantity) AS sum FROM dealer 
         > GROUP BY GROUPING SETS ((city, car_model), (city), (car_model), ()) 
         > ORDER BY city, car_model;
+--------+------------+---+
|    city|   car_model|sum|
+--------+------------+---+
|    null|        null| 78|
|    null|Honda Accord| 33|
|    null|   Honda CRV| 10|
|    null| Honda Civic| 35|
|  Dublin|        null| 33|
|  Dublin|Honda Accord| 10|
|  Dublin|   Honda CRV|  3|
|  Dublin| Honda Civic| 20|
| Fremont|        null| 32|
| Fremont|Honda Accord| 15|
| Fremont|   Honda CRV|  7|
| Fremont| Honda Civic| 10|
|San Jose|        null| 13|
|San Jose|Honda Accord|  8|
|San Jose| Honda Civic|  5|
+--------+------------+---+

再看 Union All 版的執行結果:

spark-sql> (SELECT city, car_model, sum(quantity) AS sum FROM dealer GROUP BY city, car_model) UNION ALL 
         > (SELECT city, NULL as car_model, sum(quantity) AS sum FROM dealer GROUP BY city) UNION ALL 
         > (SELECT NULL as city, car_model, sum(quantity) AS sum FROM dealer GROUP BY car_model) UNION ALL 
         > (SELECT NULL as city, NULL as car_model, sum(quantity) AS sum FROM dealer) 
         > ORDER BY city, car_model;
+--------+------------+---+
|    city|   car_model|sum|
+--------+------------+---+
|    null|        null| 78|
|    null|Honda Accord| 33|
|    null|   Honda CRV| 10|
|    null| Honda Civic| 35|
|  Dublin|        null| 33|
|  Dublin|Honda Accord| 10|
|  Dublin|   Honda CRV|  3|
|  Dublin| Honda Civic| 20|
| Fremont|        null| 32|
| Fremont|Honda Accord| 15|
| Fremont|   Honda CRV|  7|
| Fremont| Honda Civic| 10|
|San Jose|        null| 13|
|San Jose|Honda Accord|  8|
|San Jose| Honda Civic|  5|
+--------+------------+---+

兩版的查詢結果完全一樣。

Grouping Sets 的執行計劃

從執行結果上看,Grouping Sets 版本和 Union All 版本的 SQL 是等價的,但 Grouping Sets 版本更加簡潔。

那么,Grouping Sets 僅僅只是 Union All 的一個縮寫,或者語法糖嗎

為了進一步探究 Grouping Sets 的底層實現是否和 Union All 是一致的,我們可以來看下兩者的執行計劃。

首先,我們通過 explain extended 來查看 Union All 版本的 Optimized Logical Plan :

spark-sql> explain extended (SELECT city, car_model, sum(quantity) AS sum FROM dealer GROUP BY city, car_model) UNION ALL (SELECT city, NULL as car_model, sum(quantity) AS sum FROM dealer GROUP BY city) UNION ALL (SELECT NULL as city, car_model, sum(quantity) AS sum FROM dealer GROUP BY car_model) UNION ALL (SELECT NULL as city, NULL as car_model, sum(quantity) AS sum FROM dealer) ORDER BY city, car_model;
== Parsed Logical Plan ==
...
== Analyzed Logical Plan ==
...
== Optimized Logical Plan ==
Sort [city#93 ASC NULLS FIRST, car_model#94 ASC NULLS FIRST], true
+- Union false, false
   :- Aggregate [city#93, car_model#94], [city#93, car_model#94, sum(quantity#95) AS sum#79L]
   :  +- Project [city#93, car_model#94, quantity#95]
   :     +- HiveTableRelation [`default`.`dealer`, ..., Data Cols: [id#92, city#93, car_model#94, quantity#95], Partition Cols: []]
   :- Aggregate [city#97], [city#97, null AS car_model#112, sum(quantity#99) AS sum#81L]
   :  +- Project [city#97, quantity#99]
   :     +- HiveTableRelation [`default`.`dealer`, ..., Data Cols: [id#96, city#97, car_model#98, quantity#99], Partition Cols: []]
   :- Aggregate [car_model#102], [null AS city#113, car_model#102, sum(quantity#103) AS sum#83L]
   :  +- Project [car_model#102, quantity#103]
   :     +- HiveTableRelation [`default`.`dealer`, ..., Data Cols: [id#100, city#101, car_model#102, quantity#103], Partition Cols: []]
   +- Aggregate [null AS city#114, null AS car_model#115, sum(quantity#107) AS sum#86L]
      +- Project [quantity#107]
         +- HiveTableRelation [`default`.`dealer`, ..., Data Cols: [id#104, city#105, car_model#106, quantity#107], Partition Cols: []]
== Physical Plan ==
...

從上述的 Optimized Logical Plan 可以清晰地看出 Union All 版本的執行邏輯:

  1. 執行每個子查詢語句,計算得出查詢結果。其中,每個查詢語句的邏輯是這樣的:
    • HiveTableRelation 節點對 dealer 表進行全表掃描。
    • Project 節點選出與查詢語句結果相關的列,比如對于子查詢語句 SELECT NULL as city, NULL as car_model, sum(quantity) AS sum FROM dealer,只需保留 quantity 列即可。
    • Aggregate 節點完成 quantity 列對聚合運算。在上述的 Plan 中,Aggregate 后面緊跟的就是用來分組的列,比如 Aggregate [city#902] 就表示根據 city 列來進行分組。
  2. Union 節點完成對每個子查詢結果的聯合。
  3. 最后,在 Sort 節點完成對數據的排序,上述 Plan 中 Sort [city#93 ASC NULLS FIRST, car_model#94 ASC NULLS FIRST] 就表示根據 citycar_model 列進行升序排序。

圖片

接下來,我們通過 explain extended 來查看 Grouping Sets 版本的 Optimized Logical Plan:

spark-sql> explain extended SELECT city, car_model, sum(quantity) AS sum FROM dealer GROUP BY GROUPING SETS ((city, car_model), (city), (car_model), ()) ORDER BY city, car_model;
== Parsed Logical Plan ==
...
== Analyzed Logical Plan ==
...
== Optimized Logical Plan ==
Sort [city#138 ASC NULLS FIRST, car_model#139 ASC NULLS FIRST], true
+- Aggregate [city#138, car_model#139, spark_grouping_id#137L], [city#138, car_model#139, sum(quantity#133) AS sum#124L]
   +- Expand [[quantity#133, city#131, car_model#132, 0], [quantity#133, city#131, null, 1], [quantity#133, null, car_model#132, 2], [quantity#133, null, null, 3]], [quantity#133, city#138, car_model#139, spark_grouping_id#137L]
      +- Project [quantity#133, city#131, car_model#132]
         +- HiveTableRelation [`default`.`dealer`, org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe, Data Cols: [id#130, city#131, car_model#132, quantity#133], Partition Cols: []]
== Physical Plan ==
...

從 Optimized Logical Plan 來看,Grouping Sets 版本要簡潔很多!具體的執行邏輯是這樣的:

  1. HiveTableRelation 節點對 dealer 表進行全表掃描。
  2. Project 節點選出與查詢語句結果相關的列。
  3. 接下來的 Expand 節點是關鍵,數據經過該節點后,多出了 spark_grouping_id 列。從 Plan 中可以看出來,Expand 節點包含了 Grouping Sets 里的各個 grouping set 信息,比如 [quantity#133, city#131, null, 1] 對應的就是 (city) 這一 grouping set。而且,每個 grouping set 對應的 spark_grouping_id 列的值都是固定的,比如 (city) 對應的 spark_grouping_id1
  4. Aggregate 節點完成 quantity 列對聚合運算,其中分組的規則為 city, car_model, spark_grouping_id。注意,數據經過 Aggregate 節點后,spark_grouping_id 列被刪除了!
  5. 最后,在 Sort 節點完成對數據的排序。

圖片

從 Optimized Logical Plan 來看,雖然 Union All 版本和 Grouping Sets 版本的效果一致,但它們的底層實現有著巨大的差別。

其中,Grouping Sets 版本的 Plan 中最關鍵的是 Expand 節點,目前,我們只知道數據經過它之后,多出了 spark_grouping_id 列。而且從最終結果來看,spark_grouping_id只是 Spark SQL 的內部實現細節,對用戶并不體現。那么:

  1. Expand 的實現邏輯是怎樣的,為什么能達到 Union All 的效果?
  2. Expand 節點的輸出數據是怎樣的
  3. spark_grouping_id 列的作用是什么

通過 Physical Plan,我們發現 Expand 節點對應的算子名稱也是 Expand:

== Physical Plan ==
AdaptiveSparkPlan isFinalPlan=false
+- Sort [city#138 ASC NULLS FIRST, car_model#139 ASC NULLS FIRST], true, 0
   +- Exchange rangepartitioning(city#138 ASC NULLS FIRST, car_model#139 ASC NULLS FIRST, 200), ENSURE_REQUIREMENTS, [plan_id=422]
      +- HashAggregate(keys=[city#138, car_model#139, spark_grouping_id#137L], functions=[sum(quantity#133)], output=[city#138, car_model#139, sum#124L])
         +- Exchange hashpartitioning(city#138, car_model#139, spark_grouping_id#137L, 200), ENSURE_REQUIREMENTS, [plan_id=419]
            +- HashAggregate(keys=[city#138, car_model#139, spark_grouping_id#137L], functions=[partial_sum(quantity#133)], output=[city#138, car_model#139, spark_grouping_id#137L, sum#141L])
               +- Expand [[quantity#133, city#131, car_model#132, 0], [quantity#133, city#131, null, 1], [quantity#133, null, car_model#132, 2], [quantity#133, null, null, 3]], [quantity#133, city#138, car_model#139, spark_grouping_id#137L]
                  +- Scan hive default.dealer [quantity#133, city#131, car_model#132], HiveTableRelation [`default`.`dealer`, ..., Data Cols: [id#130, city#131, car_model#132, quantity#133], Partition Cols: []]

帶著前面的幾個問題,接下來我們深入 Spark SQL 的 Expand 算子源碼尋找答案。

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

    關注

    8

    文章

    7067

    瀏覽量

    89110
  • SQL
    SQL
    +關注

    關注

    1

    文章

    766

    瀏覽量

    44161
  • 函數
    +關注

    關注

    3

    文章

    4333

    瀏覽量

    62691
收藏 人收藏

    評論

    相關推薦

    在Delphi動態地使用SQL查詢語句

    程序的查詢語句。假定程序的窗體中有一個名為Query1的TQuery構件,在程序運行過程需要改變它的SQL查詢
    發表于 05-10 11:10

    SQL語句的兩種嵌套方式

    一般情況下,SQL語句是嵌套在宿主語言(如C語言)的。有兩種嵌套方式:1.調用層接口(CLI):提供一些庫,庫的函數和方法實現
    發表于 05-23 08:51

    區分SQL語句與主語言語句

    為了區分SQL語句與主語言語句,所有SQL 語句必須加前綴EXEC SQL處理過程:含嵌入式
    發表于 10-28 08:44

    為什么要動態sql語句

    為什么要動態sql語句?因為動態sql語句能夠提供一些比較友好的機制1、可以使得一些在編譯過程
    發表于 12-20 06:00

    數據庫SQL語句電子教程

    電子發燒友為您提供了數據庫SQL語句電子教程,幫助您了解數據庫 SQL語句 ,學習讀懂數據庫SQL語句
    發表于 07-14 17:09 ?0次下載

    sql語句實例講解

    SQL是用來存取關系數據庫的語言,具有查詢、操縱、定義和控制關系型數據庫的四方面功能。常見的關系數據庫有Oracle,SQLServer,DB2,Sybase。開源不收費的有MYSQL,SQLLite等。今天我們主要以MYSQL為例子,講解SQL常用的
    發表于 11-17 12:39 ?9145次閱讀
    <b class='flag-5'>sql</b><b class='flag-5'>語句</b>實例講解

    如何使用navicat或PHPMySQLAdmin導入SQL語句

    很多朋友問我們怎么導入SQL語句,這是新人最需要知道的東西,現制作圖文教程,希望對新手有所幫助,順便文末附SQL語句導入導出大全,高手可以提供更加詳細的教程。
    發表于 04-10 15:06 ?2次下載

    VSSQL命令語句的詳細資料免費下載

    本文檔的主要內容詳細介紹的是微軟VS(Microsoft Visual Studio)SQL命令語句的詳細資料免費下載
    發表于 10-09 11:45 ?8次下載

    如何使用SQL修復語句程序說明

    本文檔的主要內容詳細介紹的是如何使用SQL修復語句程序說明。
    發表于 10-31 15:09 ?5次下載

    嵌入式SQL語句

    為了區分SQL語句與主語言語句,所有SQL 語句必須加前綴EXEC SQL處理過程:含嵌入式
    發表于 10-21 11:51 ?4次下載
    嵌入式<b class='flag-5'>SQL</b><b class='flag-5'>語句</b>

    Group By高級用法Groupings Sets語句的功能和底層實現

    SQL Group By 語句大家都很熟悉,根據指定的規則對數據進行分組,常常和聚合函數一起使用。
    的頭像 發表于 07-04 10:26 ?3253次閱讀

    Java如何解析、格式化、生成SQL語句

    昨天在群里看到有小伙伴問,Java里如何解析SQL語句然后格式化SQL,是否有現成類庫可以使用?
    的頭像 發表于 04-10 11:59 ?984次閱讀

    深度剖析SQLGrouping Sets語句2

    SQL `Group By` 語句大家都很熟悉, **根據指定的規則對數據進行分組** ,常常和**聚合函數**一起使用。
    的頭像 發表于 05-10 17:44 ?602次閱讀
    <b class='flag-5'>深度</b><b class='flag-5'>剖析</b><b class='flag-5'>SQL</b><b class='flag-5'>中</b>的<b class='flag-5'>Grouping</b> <b class='flag-5'>Sets</b><b class='flag-5'>語句</b>2

    sql查詢語句大全及實例

    SQL(Structured Query Language)是一種專門用于數據庫管理系統的標準交互式數據庫查詢語言。它被廣泛應用于數據庫管理和數據操作領域。在本文中,我們將為您詳細介紹SQL查詢語句
    的頭像 發表于 11-17 15:06 ?1526次閱讀

    oracle執行sql查詢語句的步驟是什么

    Oracle數據庫是一種常用的關系型數據庫管理系統,具有強大的SQL查詢功能。Oracle執行SQL查詢語句的步驟包括編寫SQL語句、解析
    的頭像 發表于 12-06 10:49 ?985次閱讀
    主站蜘蛛池模板: 亚洲精品国产在线观看| 麻1豆传媒2021精品| 亚洲三级黄色片| 女生下面免费看| 国内精品久久久久影院老司| vivoe另类| 一个人免费视频在线观看高清频道| 全部老头和老太XXXXX| 久久精品国产在热亚洲完整版| 成人小视频免费在线观看| 在线亚洲精品国产一区麻豆| 忘忧草在线| 囚禁固定在调教椅上扩张H| 久久九九亚洲精品| 国产亚洲va在线电影| 大胸美女洗澡扒奶衣挤奶| 3DNagoonimation动漫| 亚洲精品国偷拍自产在线 | 久久精品视频在线看99| 国产成人女人视频在线观看| 99在线观看| 羽月希被黑人吃奶dasd585| 午夜福利免费院| 日韩AV爽爽爽久久久久久| 欧美 亚洲 中文字幕 高清| 空姐厕所啪啪啪| 久久www99re在线播放| 国拍自产精品福利区| 国产激情精品久久久久久碰| 岛国片免费在线观看| 超碰97人人做人人爱少妇| 99久久e免费热视频百度| 18禁国产精品久久久久久麻豆| 亚洲午夜精品一区二区公牛电影院 | 精品高潮呻吟99AV无码| 国产日韩欧美有码在线视频| 囯产精品一区二区三区线| 哒哒哒高清视频在线观看| 春暖花开 性 欧洲| 大胸美女脱内衣黄网站| 第一福利视频网站在线|