Spark SQL整體架構
從上圖可見,無論是直接使用 SQL 語句還是使用 DataFrame,都會經過如下步驟轉換成 DAG 對 RDD 的操作
1) Parser 解析 SQL,生成 Unresolved Logical Plan
在Unresolved Logical Plan中,不知道涉及表是什麼類型,資料存在何處,表的結構是什麼;
這一步主要完成詞法和文法解析,生成解析樹
2)由 Analyzer 結合 Catalog 資訊生成 Resolved Logical Plan
Catalog中包括表名稱、表字段名稱和字段類型等。借助catalog完成資料,類型,操作的綁定。
有了這些資訊,已經可以直接将該 LogicalPlan 轉換為 Physical Plan 進行執行。但每個使用者送出的SQl品質不一樣,直接執行會導緻執行效率差距太大。是以需要進行SQL優化
3) Optimizer根據預先定義好的規則對 Resolved Logical Plan 進行優化并生成 Optimized Logical Plan
基于預先定義好的規則也叫做RBO (Rule-based optimization),優化思路主要是減少參與計算的資料量以及計算本身的代價。
1)PushdownPredicate 是最常見的用于減少參與計算的資料量的方法
例如在兩表進行 Join 操作,然後再 進行 Filter 操作。引入 PushdownPredicate 後,可先對兩表進行 Filter 再進行 Join;此處的優化是 LogicalPlan 的優化,從邏輯上保證了将 Filter 下推後由于參與 Join 的資料量變少而提高了性能。
此外ColumnPruning 也是将選擇的字段提前select出來減少計算量的方法。
2)ConstantFolding是減少計算本身代價的方法
例如select 100+80+math_score+english_score,如果不進行優化,那如果有一億條記錄,就會計算一億次 100 + 80,非常浪費資源。是以可通過 ConstantFolding 将這些常量合并,進而減少不必要的計算,提高執行速度。
以上優化都是基于邏輯層面的優化,進而帶來實際執行時實體效率的提高
4)Query Planner 将 Optimized Logical Plan 轉換成多個 Physical Plan
5) CBO 根據 Cost Model 算出每個 Physical Plan 的代價并選取代價最小的 Physical Plan 作為最終的Physical Plan
BRO屬于 LogicalPlan 的優化,所有優化均基于 LogicalPlan 本身的特點,未考慮資料本身的特點,也未考慮算子本身的代價。 是以CBO充分考慮了資料本身的特點(如大小、分布)以及操作算子的特點(中間結果集的分布及大小)及代價,進而更好的選擇執行代價最小的實體執行計劃,
6)Spark 以 DAG 的方法執行上述 Physical Plan 在執行 DAG 的過程中,Adaptive Execution 根據運作時資訊動态調整執行計劃進而提高執行效率
這一步還存在着将實體執行計劃轉變成可執行實體計劃
參考:
https://www.cnblogs.com/qoix/p/9649310.html
https://blog.csdn.net/junerli/article/details/78607708
https://www.2cto.com/net/201805/742744.html
https://blog.csdn.net/junerli/article/details/78607708
https://blog.csdn.net/zhanglh046/article/details/78360980
https://www.cnblogs.com/moon0201/p/10415178.html