本文分享自華為雲社群《【GaussTech第2期】GaussDB SQL查詢語句執行過程解析》,作者: GaussDB 資料庫。
SQL於關係型資料庫而言,重要性不言而喻。就像一個樂團的指揮,指導著作品的正確演繹和節奏的和諧統一。華為雲GaussDB作為新一代關係型分散式資料庫,具備卓越的技術效能和行業競爭力。很多人對GaussDB的關鍵技術很好奇,紛紛在論壇帖上留言:
今天我們就從GaussDB SQL引擎入手,瞭解一下GaussDB SQL查詢語句的執行過程,包括GaussDB SQL引擎原理和關鍵技術點。
如果您在瞭解的過程中有任何疑問或感興趣的關鍵技術點,可參與【雲咖問答】揭開GaussDB SQL引擎的神秘面紗,互動交流贏好禮活動,進行留言互動,專家會一對一進行答疑哦,更有機會獲得提問好禮激勵。
↓↓↓↓ 以下是正文
首先,簡單介紹一下GaussDB的系統結構,再解析GaussDB SQL查詢語句的執行過程。
GaussDB系統架構
圖(1) 集中式
圖(2) 分散式
在GaussDB SQL語句執行過程中,會涉及以下幾個關鍵角色:
GTM |
全域性事務管理器(Global Transaction Manager),負責生成和維護全域性事務ID、事務快照、時間戳、sequence資訊等全域性唯一的資訊。 |
CN |
協調節點(Coordinator Node)。負責接收來自應用的訪問請求,並向客戶端返回執行結果;負責分解任務,並排程任務分片在各DN上並行執行。每個CN與每個DN相連線,每個CN各持有一份後設資料,後設資料內容相同。 |
DN |
資料節點(Data Node)。負責儲存業務資料(支援行存、列存、混合儲存)、執行資料查詢任務以及向CN返回執行結果。 |
其中,DN主要承擔GaussDB SQL語句的執行,其邏輯架構如下圖所示:
圖(3) GaussDB邏輯架構
GaussDB包括兩個主要引擎:SQL引擎 (SQL Engine) 和儲存引擎 (Storage Engine) 。SQL引擎有時也被稱為查詢處理器,它的主要功能是SQL 解析、查詢最佳化和查詢執行。SQL解析對輸入的 SQL 語句進行詞法解析、語法解析、語義解析,從而生成查詢樹。查詢樹經過規則最佳化(RBO)和代價最佳化(CBO)之後,產生執行計劃。執行器基於該執行計劃對相關資料進行提取、運算、更新、刪除等操作,以達到使用者查詢想要實現的結果。
儲存引擎負責管理所有資料的I/O,它包含資料讀寫處理(處理行、索引、頁、分配和行版本的I/O請求)、資料緩衝管理(Buffer Pool)和事務管理器。其中,事務管理又涉及到保持ACID屬性的鎖機制(Lock)和事務日誌管理(XLOG)。
在SQL引擎和儲存引擎之間是AM(Access Method) 層。AM對儲存層做了封裝,以支援多種儲存引擎(Astore,Ustore,etc.)。SQL層不直接呼叫儲存層,而是透過AM層,AM層會根據不同的儲存引擎呼叫不同的執行體。
從GaussDB邏輯架構圖中可以看出,GaussDB架構設計遵循現代軟體系統抽象化和分層解耦的設計原則,包括:統一事務機制、統一日誌系統、統一併發控制系統、統一元資訊系統、統一快取管理系統。因此,GaussDB技術架構具備以下主要特點:
-
支援SQL最佳化、執行、儲存分層解耦;
-
支援可插拔儲存引擎。
SQL查詢語句的執行過程
一條SQL查詢(SELECT)語句的執行過程,如下所示:
圖(4) 查詢語句的執行過程
從上圖可以看出,一條SQL語句需要經過SQL解析生成查詢樹、查詢最佳化生成執行計劃,然後將執行計劃轉交給查詢執行器做物理運算元的執行操作。
SQL是介於關係演算和關係代數之間的一種描述性語言,它吸取了關係代數中一部分邏輯運算元的描述,而放棄了關係代數中 “過程化” 的部分。SQL解析主要的作用就是將一個SQL語句編譯成為一個由關係運算元組成的查詢樹,通常包含詞法解析、語法解析、語義解析幾個子模組。
規則最佳化(RBO)則是在查詢樹的基礎上進行等價的關係代數變換,把一條SQL語句轉換為更高效的等價SQL,並在資料庫最佳化器中扮演關鍵角色。尤其在複雜查詢中,它能夠在效能上帶來數量級的提升。
查詢執行是根據執行計劃來執行SQL查詢語句。底層儲存方式的選擇合理性,將影響查詢執行效率。
解析器
1.詞法解析:從查詢語句中識別出系統支援的關鍵字、識別符號、運算子、終結符等,確定每個詞固有的詞性。
SQL標準定義了SQL的關鍵字以及語法規則資訊,GaussDB在做詞法分析過程中會將一個SQL語句根據關鍵字資訊以及間隔資訊劃分為獨立的原子單位,每個單位以一個詞的方式展現。
2. 語法解析:根據定義的SQL語法規則,使用詞法分析中產生的詞去匹配語法規則,並生成對應的抽象語法樹(Abstract Syntax Tree,AST)。
3. 語義解析:對語法樹進行有效性檢查,檢查語法樹中對應的表、列、函式、表示式是否有對應的後設資料,將抽象語法樹轉換為查詢樹。
語義解析的過程也是有效性語義繫結的過程,透過語義分析的檢查,抽象語法樹就轉換成一個查詢樹。查詢樹可以透過關係代數表示式的形式來表現。
最佳化器
最佳化器是提升查詢效率非常重要的一個手段,它包括規則最佳化和查詢最佳化兩部分。
規則最佳化是在查詢樹的基礎上進行等價的關係代數變換,由於它是建立在關係代數基礎之上的最佳化形式,也可稱為代數最佳化。雖然兩個關係代數式獲得的結果完全相同,但是它們的執行代價卻可能有很大的差異,這就構成了規則最佳化的基礎。
規則最佳化遵循兩個基本原則:
(1)等價性:原語句和重寫後的語句輸出結果相同。
(2)高效性:重寫後的語句比原語句執行時間短,且資源使用更高效。
GaussDB實現了一些關鍵的規則最佳化技術,例如:
謂詞下推:更早地觸發條件過濾,減少處理行數
冗餘運算消除:消除冗餘的表、列,減少計算量
子查詢提升:提升後可以匹配更多連線順序
Outer-To-Inner轉換:Inner Join可以匹配更多連線順序
子連結提升:減少subplan和Broadcast運算
消除不等值連線:減少NestLoop和Broadcast運算
在服務大量的客戶過程中,GaussDB對業務 SQL使用模式進行抽象,並實現了一些高階重寫規則。在今後的欄目中,我們會對GaussDB的規則最佳化技術做詳細介紹。
查詢最佳化
查詢最佳化是根據“規則最佳化”的輸出,結合資料庫內部統計資訊來規劃SQL語句具體的執行方式,也就是執行計劃。基於最佳化方法的不同,查詢最佳化技術可以分為:
(1)CBO(Cost Based Optimization,基於代價的查詢最佳化):對SQL語句對應的待選執行路徑進行代價估算,從待選路徑中選擇代價最低的執行路徑作為最終的執行計劃。
(2)ABO(AI Based Optimization,基於機器學習的查詢最佳化):透過對歷史經驗的不斷學習,ABO將目標場景的模式進行抽象化,形成動態的模型,自適應地針對使用者的實際場景進行最佳化,從而獲得最優的執行計劃。
GaussDB採用基於CBO的最佳化技術,並結合ABO在建模效率、估算準確率和自適應性等方向進行積極探索,步驟如下:
圖(5) 查詢最佳化步驟
統計資訊模型:統計資訊是計算計劃路徑代價的基石,統計資訊的準確度對代價估算模型中行數估算和代價估算起著至關重要的作用,直接影響查詢計劃的優劣。GaussDB基表資料的特徵包括distinct值、MCV (Most Common Values) 值、直方圖等。
行數估算 (Row Estimation):當一個約束條件確定了選擇率之後,就可以確定每個計劃路徑所需要處理的行數,並根據行數推算出所需要處理的頁面數,為代價估算做準備。
代價估算 (Cost Estimation):根據資料量估算不同運算元執行代價,各運算元代價之和即為計劃的總代價。
當計劃路徑處理頁面的時候,會產生I/O代價,而當計劃路徑處理元組的時候(例如,針對元組做表示式計算 ),會產生CPU代價。由於GaussDB是分散式資料庫,在CN和DN之間傳輸資料又會產生通訊代價,因此一個計劃的總代價可以表示為:
總代價 = IO代價 + CPU代價 + 通訊代價
-
路徑搜尋:透過求解路徑最優演算法(動態規劃、遺傳演算法)處理連線路徑搜尋過程,以最小搜尋空間找到最優連線路徑。
GaussDB採用的是自底向上和隨機搜尋模式相結合的方式。搜尋過程也都是一個從查詢樹向執行計劃轉變的過程,例如針對每個表可以有不同的掃描運算元,而邏輯連線運算元也可以轉換為多種不同的物理連線運算元。
-
計劃生成:將查詢執行路徑轉換成執行計劃(PlanTree),提供給執行器執行。
查詢最佳化可能需要花費較長時間,特別是在處理複雜查詢時。計劃快取是GaussDB的一個重要功能,它可以快取查詢語句的執行計劃,以便在下次執行相同查詢時可以直接使用快取中的執行計劃,從而避免重複計算和最佳化查詢效能。
分散式查詢最佳化
作為原生分散式資料庫,分散式查詢最佳化技術尤為重要。
GaussDB分散式架構充分運用每個節點的計算資源,且隨著節點規模的擴大其整體效能也呈線性增長。為了實現分散式架構下效能和資源的利用最大化,GaussDB支援四種分散式計劃,分別為CN 輕量化計劃、FQS(Fast Query Shipping)計劃、Stream計劃和Remote-Query計劃,如下圖所示:
圖(6) 四種分散式計劃
-
CN 輕量化: 語句直接下發到單個 DN 上執行(LIGHT_PROXY)
-
執行原理:CN透過socket直接下發語句QPBE報文到對應DN。
-
適用場景:語句可以直接在一個DN執行(單shard語句)。
-
FQS(Fast Query Shipping)語句下發: 下發SQL語句的計劃
(REMOTE_FQS_QUERY)
-
執行原理:CN不透過最佳化器,直接生成RemoteQuery計劃,走執行器邏輯下發到DN。各DN根據下推語句生成執行計劃並進行執行,執行結果在CN上進行彙總。
-
適用場景:語句可以完全下推到多個DN上執行,且DN之間不需要資料互動。
-
STREAM 計劃下發:下發SQL計劃的分散式計劃(STREAM)
-
執行原理:CN根據原語句透過最佳化器生成帶stream運算元的執行計劃,下發給DN進行執行,DN執行過程中存在資料互動(stream節點)。stream運算元在DN之間建立連線進行資料互動,CN彙總執行結果。DN承擔了大部分計算。
-
適用場景:執行時CN和DN之間、DN和DN之間有資料互動的複雜語句。
-
Remote-Query 計劃:下發部分SQL語句的分散式計劃 (REMOTE_QUERY)
-
執行原理:CN透過最佳化器把原語句中的部分語句生成RemoteQuery計劃,把每個RemoteQuery下發到DN,DN執行後把中間結果資料傳送給CN,CN收集後進行剩餘執行計劃的執行計算,因此,CN承擔了大部分計算。
-
適用場景:不滿足前三種生成條件的極少數場景,效能非常差。
在分散式架構下,同一個表的資料會分佈到不同的資料節點上,建立表的時候可以選擇將資料在每個表上做雜湊(Hash)分佈或者隨機分佈。為了正確執行兩表連線操作,有可能需要將兩個表的資料重新分佈,因此,GaussDB的分散式執行計劃中增加了三個使資料形成特定分佈方式的Stream運算元。
圖(7) Stream運算元
分散式路徑生成時,會考慮兩表及連線條件上的資料是否處於同一個資料節點,如果不是,則會新增相應的資料分發運算元。根據降低資料在DN節點間流動的原則來選擇重分佈的Stream運算元。
正是基於Stream運算元的合理運用,GaussDB在分散式架構下處理大規模資料才成為可能。針對Stream運算元的最佳化也是GaussDB 查詢最佳化的重要部分。
圖(8) GaussDB分散式查詢最佳化技術
【關鍵技術點】分散式查詢最佳化:四種分散式執行計劃、三個Stream運算元。
執行器
執行器接收到的指令就是由最佳化器針對SQL查詢語句而產生的執行計劃,而執行計劃是由一些執行運算元(Operator)、表示式等組成,主要是對關係集合進行運算,最終輸出使用者想要的結果集。下面是幾類常見的執行運算元:
1. 掃描運算元(Scan Plan Node)
掃描節點負責從底層資料來源抽取資料,資料來源可能是來自檔案系統,也可能來自網路。一般而言掃描節點都位於執行樹的葉子節 點,作為執行的資料輸入來源,典型代表SeqScan、IndexScan、 SubQueryScan 。
關鍵特徵:輸入資料、葉子節點、表示式過濾
2. 控制運算元(Control Plan Node)
控制運算元一般不對映代數運算子,是為了執行器完成一些特殊的流程引入的運算元,例如Limit、RecursiveUnion、Union。
關鍵特徵:用於控制資料流程
3. 物化運算元(Materialize Plan Node)
物化運算元一般指演算法要求,在做運算元邏輯處理的時候,要求把下層 的資料進行快取處理,因為對於下層運算元返回的資料量不可提前預 知,因此需要在演算法上考慮資料無法全部放置到記憶體的情況,例如 Agg、Sort 。
關鍵特徵:需要掃描所有資料之後才返回
4. 連線運算元(Join Plan Node) 這類運算元是為了應對資料庫中最常見的關聯操作,根據處理演算法和 資料輸入源的不同分成MergeJoin, NestLoop Join, HashJoin。
關鍵特徵:關聯查詢
5. 其它運算元
執行器的架構和技術也決定了資料庫查詢執行的整體執行效率。GaussDB執行引擎充分結合現代硬體技術的特徵,採用了諸如向量化引擎、LLVM等多種現代軟體技術,進行高效執行。
圖(9) GaussDB全並行執行架構
GaussDB 在執行分散式計劃過程中,也採用了多種技術來提升查詢執行的效能。例如,在執行復雜查詢時,會將重執行運算元下推到 DN 節點執行,如 AGG 運算元等。在下推運算元執行時,會考慮資料本地性,儘可能在本地計算,減少資料在網路中的傳輸開銷。
如果您有任何疑問,或者感興趣的關鍵技術點,可在【雲咖問答】揭開GaussDB SQL引擎的神秘面紗,互動交流,贏好禮活動帖裡進行留言,專家會一對一進行答疑哦,還有機會獲得提問激勵。
點選關注,第一時間瞭解華為雲新鮮技術~