一條 SQL 的查詢計劃生成之旅【上】


背景

Apache Calcite 作為一款開源的動態(tài)數據管理框架搏恤,由于其模塊化、可擴展萧豆、以及不和任何計算引擎綁定的特性潭陪,目前在開源項目和商業(yè)化產品中已得到廣泛的應用雄妥。不僅 Apache Flink、Apache Druid依溯、Apache Hive 等明星開源項目在使用 Calcite,騰訊天穹 Super SQL瘟则、阿里 MaxCompute黎炉、Dremio 等商業(yè)化產品的 SQL Planner 也都基于 Calcite 實現。Apache Calcite 儼然成為了 SQL Planner 層的黃金標準醋拧、事實趨勢慷嗜。

隨著近些年大數據基礎設施的不斷發(fā)展成熟,SQL 已經無可爭議地成為大數據計算引擎的主流語言丹壕,但與此同時庆械,大量新興計算引擎、數據庫項目的出現菌赖,也產生了大量 SQL 方言缭乘,運維一個企業(yè)級大數據平臺需要處理 SQL 的場景越來越多。學習和了解 Apache Calcite琉用,既能幫助我們快速理解 SQL Planner 的原理機制堕绩,又能有助于我們利用 Calcite 快速解決以處理 SQL 為中心的各類日常問題(如實現一個SQL Parser、SQL Gateway邑时、SQL Planner 等)奴紧。

我們計劃從技術實戰(zhàn)、原理講解晶丘、源碼分析等角度推出系列文章黍氮,來介紹如何利用 Apache Calcite 解決一些常見的具體問題唐含,希望對數據平臺工具研發(fā)的同學有一些幫助。本文是系列文章的第一篇沫浆,將首先介紹 Apache Calcite 的架構設計捷枯,同時以一條 SQL 在 Calcite 中的處理流程為主線,對 SQL 解析件缸、元數據驗證铜靶、執(zhí)行計劃生成及優(yōu)化、SQL 方言轉換等模塊的關鍵原理進行闡述他炊,讓讀者對 Apache Calcite 有一個初步印象争剿。關于各模塊更深入的原理講解和源碼實戰(zhàn),會在后面的系列文章中分篇進行展開痊末。

目標和收益

本文主要講解 Apache Calcite 的架構設計以及 Calcite 內部 SQL 優(yōu)化方式蚕苇,閱讀本文,能夠從以下幾點幫助到你:

整體了解 Apache Calcite 凿叠,包括架構設計和核心模塊涩笤。

從一條 SQL 處理流程視角出發(fā),通過對 Calcite SQL 解析盒件、校驗蹬碧、關系代數轉換、RBO 和 CBO炒刁、物化視圖改寫和方言轉換整體流程的講解恩沽,帶你了解一條 SQL 的 Calcite 之旅。

了解 Calcite 物化視圖改寫的兩種方式及各自優(yōu)缺點翔始。

了解 Calcite 中優(yōu)化器設計的關鍵細節(jié)罗心,以及如何實現對 SQL 方言的改寫。

希望閱讀完本篇文章后城瞎,你能夠對 Calcite 整體使用流程有一個初步的認識渤闷,下面我們進入正文。

一脖镀、Apache Calcite 架構概述

1.1 Apache Calcite 誕生背景

Apache Calcite 自 2013 年 11 月首次在 Github 上進行代碼倉庫初始化飒箭,距今已有 9 年時間。Apache Calcite 前身其實是 optiq认然。optiq 最開始則是在 Hive 項目中進行使用补憾,其主要目的是為 Hive 提供基于成本模型的優(yōu)化器。2014 年 5 月 optiq 獨立出來卷员,成為 Apache 社區(qū)的孵化項目盈匾,同年 9 月正式更名為 Apache Calcite。Calcite 的作者是 Julian Hyde毕骡,他早期還寫過 Mondrian OLAP Engine 和 olap4j API削饵,目前他不僅是 Calcite 的 VP岩瘦,同時也是 Apache Arrow、Apache Drill窿撬、Apache Druid启昧、Apache Kylin 等開源項目的 PMC。

Apache Calcite 設計的核心目標:“One planner fits all”劈伴,它期望在異構引擎密末、異構存儲之上,提供統(tǒng)一的數據管理能力跛璧,同時還提供基于關系代數的優(yōu)化器严里,它的內部各個模塊都是可擴展的,也正是因為這種設計理念追城,Apache Calcite 才會被眾多其他開源項目所使用刹碾。

1.2 Apache Calcite 架構設計

Apache Calcite 整體是按模塊化進行設計,各個模塊支持可擴展座柱,比如 SQL 語法文件迷帜、元數據、Transformation Rule(邏輯轉換規(guī)則)和 Implementation Rule(物理轉換規(guī)則)色洞、CBO 元數據獲取的 Metadata Handler戏锹、自定義RelNode 和 SqlNode類型等等,同時 Calcite 底層也支持不同引擎的 SQL 方言轉換火诸。對于 SQL Planner 的優(yōu)化框架景用,整體上 Calcite 已經搭建好,我們可以直接自定義擴展需要的差異化特性惭蹂。下面是 Calcite 各模塊的架構設計示意圖:

上圖中的所有模塊都可自定義實現,接下來讓我們對各模塊一一進行說明:

1割粮、JDBC Client 和 JDBC Server盾碗,主要負責一個 SQL 的請求響應和結果返回,可以基于 Calcite 子項目 Avatica 框架來進行實現舀瓢。

2廷雅、SQL Parser 和 Validator,Parser 主要負責對一個 SQL 進行解析京髓,生成 AST 樹航缀。Validator 主要是驗證 SQL 的元數據合法性。

3堰怨、Operator Expressions芥玉,則是將一棵 AST Tree 轉換為 RelNode關系代數的計劃樹,這樣優(yōu)化器才能識別和優(yōu)化备图。

4灿巧、Query Optimizer赶袄,Calcite 優(yōu)化器模塊,有 RBO 和 CBO 優(yōu)化器抠藕,即對 Query 的關系代數計劃樹做優(yōu)化

5饿肺、Metadata Providers,CBO 優(yōu)化器計算 Cost 時盾似,所需元數據的提供者敬辣,包括:Selectivity(選擇率)、RowCount零院、DistinctRowCount 等等溉跃。

6、Pluggable Rules门粪,Calcite 優(yōu)化規(guī)則模塊喊积,Calcite 主要有:Transformation Rule(邏輯優(yōu)化規(guī)則)和 ConverterRule(Implementation Rule),用戶可以自定義可擴展玄妈。

以上我們是從 Calcite 模塊組成視角來進行理解的乾吻,那么下面從 Calcite 底層核心源代碼類調用流轉邏輯來看:

一個 SQL 的處理邏輯,會使用SqlParser 將 SQL 解析為 SqlNode拟蜻,使SqlValidator來進行 SQL 校驗绎签,使用SqlToRelConverter來將SqlNode 轉換為RelNode關系代數,使用 RelOptPlanner(具體有HepPlanner 和VolcanoPlanner )來進行計劃優(yōu)化酝锅,同時可以通過擴展RelOptRule 诡必、BuiltInMetadata 的實現,來自定義 SQL 優(yōu)化器的邏輯搔扁。CalCite 這種可擴展的設計邏輯爸舒,極大的方便開發(fā)同學去自定義 SQL 引擎 Planner 邏輯,同時避免大家重復造輪子稿蹲。

下圖為 Calcite 底層核心代碼調用流轉示意:

二扭勉、SQL 查詢優(yōu)化器概述

2.1 SQL 查詢優(yōu)化器的用途

SQL 作為一種聲明式的查詢語言,能夠讓很多技術以及非技術人員快速入門和掌握苛聘,用戶能夠使用 SQL 快速完成業(yè)務層的查詢語義邏輯的編寫涂炎。但單純的 SQL 語言,是無法直接讓底層的計算引擎識別和運行的设哗。當 SQL 查詢請求發(fā)送到底層數據庫時唱捣,需要將 SQL 查詢語句轉換為底層數據庫的計算引擎能夠識別的模型約定定義(比如執(zhí)行計劃描述),最終讓底層計算引擎按照預定的計算邏輯執(zhí)行并返回結果网梢。

對于 SQL 優(yōu)化器的核心用途:即對用戶輸入的 SQL 查詢語句震缭,將其轉換為計算引擎能夠識別和計算的執(zhí)行計劃,由于最終轉換的可以運行計劃有很多種情形澎粟,所以優(yōu)化器需要從中選取一個最優(yōu)的執(zhí)行計劃蛀序,下發(fā)到計算引擎執(zhí)行欢瞪。這里最優(yōu)既可以結合我們的先驗經驗來判定,同時也可以從一個執(zhí)行計劃使用到的物理資源進行考量徐裸,比如使用的 CPU遣鼓、內存、磁盤 IO重贺、網絡 IO骑祟、CPU LRU Cache 等等。SQL 優(yōu)化器的核心邏輯:就是對關系代數計劃做等價轉換气笙,在不改變計劃語義的情況下次企,盡可能最大化的對關系代數計劃做優(yōu)化。

2.2 SQL 查詢優(yōu)化器的優(yōu)化方式

常見的 SQL 優(yōu)化有兩種方式:RBO 優(yōu)化(基于先驗經驗的啟發(fā)式規(guī)則優(yōu)化)和 CBO 優(yōu)化(基于計算成本的優(yōu)化)潜圃。RBO 主要是使用一些預定義的先驗且有收益的優(yōu)化規(guī)則集合缸棵,來對 SQL 進行優(yōu)化,常見的有:常量折疊谭期、謂詞下推堵第、列裁剪、關聯子查詢消除等優(yōu)化規(guī)則隧出。下圖以謂詞下推優(yōu)化舉例:


上圖左邊是原始 SQL 計劃踏志,可以看到,通過 Filter 謂詞下推規(guī)則優(yōu)化后胀瞪,Filter 節(jié)點已經下推到了 Join 節(jié)點之下针余,這樣能夠提前對 Scan 節(jié)點的數據進行過濾,最終減少進入到 Join 算子的數據量凄诞,減少 Join 節(jié)點的計算成本圆雁。

當然,根據先驗經驗主義的優(yōu)化方式也存在缺陷帆谍,可能在部分場景摸柄,由于沒有考慮到 SQL 在真實環(huán)境下的實際運行情況,其執(zhí)行效率并不是最優(yōu)的既忆,所以就有了基于 Cost 的優(yōu)化方式(CBO)。CBO 優(yōu)化嗦玖,則是在期望的物理特質下患雇,通過對不同物理計劃運行所需要的成本進行估算,使用動態(tài)規(guī)劃宇挫,來選擇一個計算成本最優(yōu)的物理計劃苛吱。一般 Cost 包括:CPU、內存器瘪、磁盤 IO翠储、網絡 IO 等等绘雁。

當然,隨著技術的演進援所,現在在 RBO 優(yōu)化階段庐舟,其實也可以基于 Cost 來評估某些優(yōu)化規(guī)則是否應該使用。這里以 Group By(聚合) 下推舉例:


在上圖中住拭,如果 LogicalJoin 之后的基數(輸出的行數)如果比 LogicalTableScan[A] 后的基數要小的話挪略,Aggregate 不下推,其實會比下推更節(jié)約資源滔岳。但完全進入 CBO 階段杠娱,如果計劃搜索空間過大的話,CBO 找出最優(yōu)計劃的耗時可能又很久谱煤。所以在使用 RBO 優(yōu)化規(guī)則時摊求,某些規(guī)則可以比較轉換前后的計劃的 Cost ,來決定是否應用該規(guī)則刘离。目前業(yè)界像 Oracle 和 MemSQL(SingStoreDB)在它們的優(yōu)化器都已經這樣進行實現室叉。

2.3 SQL 查詢優(yōu)化器的框架類型

目前業(yè)界的 SQL 優(yōu)化器框架類型有:Volcano、Cascades寥闪、Columbia太惠、Orca 等優(yōu)化器框架,比較主流的優(yōu)化器框架為 Cascades疲憋,像微軟的 SQL Server凿渊、阿里 ADB、PingCAP 的 TIDB缚柳、CockroachDB埃脏、StarRocks 這些商業(yè)化產品,其 SQL 優(yōu)化器都是基于 Cascades 優(yōu)化器框架的秋忙。

Columbia彩掐、Orca 這兩款優(yōu)化器框架都是在 Cascades 優(yōu)化器基礎上,做了部分改良和優(yōu)化灰追。以 Columbia 優(yōu)化器框架舉例堵幽,其在 Cascades 優(yōu)化器基礎上,對于搜索計劃空間剪枝做得更好弹澎,不僅能夠基于 Group 空間計劃剪枝朴下,同時也能夠做全局計劃剪枝,這樣在一個可以接收并近似最優(yōu)計劃的前提下苦蒿,通過剪枝來減少 Plan 空間搜索的時間殴胧,提升查詢性能。Orca 則是能夠作為獨立的優(yōu)化器在數據庫系統(tǒng)之外運行,這樣的好處在于優(yōu)化器不需要和數據庫系統(tǒng)緊密耦合在一起团滥,但需要提供一種能夠和數據庫系統(tǒng)的交互通信機制來處理查詢竿屹。

Cascades 優(yōu)化器相對于 Volcano 優(yōu)化器最大的區(qū)別在于:Volcano 優(yōu)化器會先盡可能枚舉所有的執(zhí)行計劃空間,然后再從中找出最優(yōu)的執(zhí)行計劃灸姊。而 Cascades 優(yōu)化器能夠在搜索過程中拱燃,對空間搜索計劃進行剪枝,使得搜索的執(zhí)行計劃空間不會像 Vocano 那么大厨钻,但也可以獲得一個相對較好的執(zhí)行計劃扼雏,這樣通過減少空間計劃的搜索時間,來降低 SQL Planning 的耗時夯膀,從而提升查詢性能诗充。

2.4 一條 SQL 在 Apache Calcite 的優(yōu)化旅程

在一個典型的 SQL 查詢服務中,從用戶輸入一條 SQL 語句開始诱建,到最終結果返回到 Client蝴蜓,一般會經過:Client 端 SQL 查詢請求、服務端接收到 SQL 請求和內部作業(yè)構建俺猿、SQL 解析茎匠、SQL 校驗、SQL 優(yōu)化押袍,繼而形成物理計劃诵冒。如果底層有自己的計算引擎,還可以將物理計劃轉換為執(zhí)行計劃谊惭,下發(fā)到計算節(jié)點并執(zhí)行汽馋。如果底層計算引擎是其他引擎的話,可以將物理計劃翻譯成對應引擎的 SQL 方言圈盔,然后提交到對應引擎執(zhí)行豹芯。

為了方便讀者更具象地理解Aapche Calcite的每個模塊的運作細節(jié),本文選擇了從第二種方式出發(fā)驱敲,以實現一個SQL優(yōu)化改寫器為例铁蹈,來展開介紹一條SQL在 Apache Calcite是如何完成解析、優(yōu)化與改寫的众眨。


如上圖所示握牧,一條 SQL 整體處理流程分為以下幾個步驟:

當 Client 層發(fā)起一條 SQL 請求時,請求會到 JDBC Server 端娩梨,JDBC Server 端底層一般可以是 GRPC 服務或者 HTTP 服務我碟,在 Calcite 中,也可以使用 Calcite Avatica 來做 JDBC 服務端和 Driver 層的代碼開發(fā)姚建。

服務端接收到 SQL 請求后,會在內部構建出一個 Job 作業(yè)請求吱殉,同時提交到內部作業(yè)服務掸冤,之后會進入到 SQL 鏈路處理流程中厘托。

在 SQL 處理流程中,第一步則是將 SQL 解析成一棵 SqlNode 的 AST 抽象語法樹稿湿,這個過程中會做 SQL 詞法和語法的校驗铅匹。之后會進入到 SQL 驗證階段,SQL 驗證階段主要對 SQL 的語義進行驗證饺藤,比如查詢的數據表是否存在包斑、函數是否存在、函數參數數據類型是否匹配等等涕俗。元數據驗證完之后罗丰,其輸出本質還是一棵 SqlNode 樹,接下來會將 SqlNode Tree 轉換為一棵RelNode 關系代數 Tree再姑,同時進入到 SQL 優(yōu)化階段萌抵。

在 Calcite 中,RBO 優(yōu)化主要使用HepPlanner類來進行實現元镀。CBO 優(yōu)化绍填,則是使用 VolcanoPlanner來進行實現,RBO 規(guī)則和 CBO 規(guī)則都支持自定義擴展栖疑。

經過 SQL 優(yōu)化器的優(yōu)化讨永,會產出最優(yōu)的物理計劃。但這還無法最終運行遇革,還需要將物理計劃轉化為底層計算引擎的 SQL 方言卿闹,進行作業(yè)的提交和計算。

本次先分享到這里澳淑,下一篇比原,我們將進入 Apache Calcite 各組件模塊關鍵原理解析。最后杠巡,如果你對數據虛擬化量窘、Calcite 原理技術、湖倉平臺氢拥、SQL 優(yōu)化器感興趣的話蚌铜,歡迎關注“Aloudata技術團隊”公眾號。



??本文作者/?沈浪嫩海,Aloudata OLAP 引擎研發(fā)專家, 畢業(yè)于電子科技大學冬殃,曾就職于阿里、有贊叁怪、字節(jié)的基礎設施團隊审葬,參與數據倉庫、實時計算、數據湖核心研發(fā)涣觉,現負責Aloudata 湖倉查詢引擎 SQL 查詢優(yōu)化器的研發(fā)工作痴荐。



Aloudata浙江大應科技-技術部誠聘Java技術專家/高級技術專家,高級數據庫內核研發(fā)專家官册,Base杭州生兆。同時,我們針對24屆實習生招聘已經開始啦膝宁,歡迎有興趣的同學投遞簡歷至:wuque.hua@aloudata.com鸦难。積蓄星火,以待磅礴员淫,Aloudata技術團隊期待與你共同探索NoETL新世界合蔽,領跑數據智能新未來!

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末满粗,一起剝皮案震驚了整個濱河市辈末,隨后出現的幾起案子,更是在濱河造成了極大的恐慌映皆,老刑警劉巖挤聘,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異捅彻,居然都是意外死亡组去,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進店門步淹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來从隆,“玉大人,你說我怎么就攤上這事缭裆〖耄” “怎么了?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵澈驼,是天一觀的道長辛燥。 經常有香客問我,道長缝其,這世上最難降的妖魔是什么挎塌? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮内边,結果婚禮上榴都,老公的妹妹穿的比我還像新娘。我一直安慰自己漠其,他們只是感情好嘴高,可當我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布竿音。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪土全。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天,我揣著相機與錄音帝牡,去河邊找鬼。 笑死昧诱,一個胖子當著我的面吹牛拥刻,可吹牛的內容都是我干的。 我是一名探鬼主播线罕,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼止潮,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了钞楼?” 一聲冷哼從身側響起喇闸,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎询件,沒想到半個月后燃乍,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡宛琅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年刻蟹,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嘿辟。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡舆瘪,死狀恐怖,靈堂內的尸體忽然破棺而出红伦,到底是詐尸還是另有隱情英古,我是刑警寧澤,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布昙读,位于F島的核電站召调,受9級特大地震影響,放射性物質發(fā)生泄漏箕戳。R本人自食惡果不足惜某残,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望陵吸。 院中可真熱鬧玻墅,春花似錦、人聲如沸壮虫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至剩拢,卻和暖如春线得,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背徐伐。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工贯钩, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人办素。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓角雷,卻偏偏與公主長得像,于是被迫代替她去往敵國和親性穿。 傳聞我的和親對象是個殘疾皇子勺三,可洞房花燭夜當晚...
    茶點故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內容