「分散式技術專題」剖析一個SQL的解析及執行過程

Hubble資料庫發表於2023-02-13

無所不能的程式猿吐出一句魔法 SQL ,剎那間,IO 猶如千軍萬馬奔流不息,記憶體似鯨吸牛飲,海納百川,CPU 更是狂暴著以 360% 負荷高速運轉,瞬間,一個美妙的身影出現了……

一條SQL的背後,資料庫到底做了什麼,本文將深入淺出的聊一下 SQL 的解析和執行過程。

1. SQL簡介

SQL 是上世紀 70 年代,基於關係型資料庫發明的一種簡潔的資料操作語言。
SQL 按 功能可以分為以下 三種型別

「分散式技術專題」剖析一個SQL的解析及執行過程

業務模型與 SQL 的關係: SQL 是業務本質的濃縮,如以下銀行或證券行業的常見業務:

「分散式技術專題」剖析一個SQL的解析及執行過程

每個業務模型,最終都會轉化為一條SQL語句的執行。SQL中包含了你要查詢的實體表名稱,分組、排序欄位,過濾條件等等。

2. SQL的生命週期

生活中,我們做事的步驟一般是先設定目標、然後制定計劃、最後實踐。
資料庫中,一條 SQL 語句就是要完成的目標;SQL 會被編譯器解析生成執行計劃;最後交由執行器去儲存引擎中完成實際的資料操作。
詳細的生命週期可以劃分為建立連線、詞法和語法解析、邏輯計劃、RBO 和 CBO 最佳化、執行計劃、許可權檢查、資源排程、分散式任務執行、返回最終結果等階段。

2.1 建立連線

客戶端使用 JDBC 或 ODBC 協議,提交一個 SQL ,到伺服器端。

2.2 詞法和語法解析

詞法分析是編譯過程的第一個階段,目的是將輸入的各種符號,轉化成相應的識別符號(token),可以被後續階段處理。
詞法分析程式一般稱之為Lexical analyzer 或 Scanner。

「分散式技術專題」剖析一個SQL的解析及執行過程

語法分析是編譯過程的一個邏輯階段; 此階段的任務是在詞法分析的基礎上將單詞序列組合成各類語法短語、表示式等。 語法分析程式一般稱之為  Parser 。
SQL 解析的本質是語言轉換,就是把文字程式碼轉換成計算機語言能描述的資料結構。

  • 常用 SQL 編譯工具介紹 

    • lexical compiler ,是一個詞法分析器(scanner)的生成工具, 使用正規表示式來描述各個詞法單元。

    • Yacc 是一個經典的生成語法分析器的工具,採用自下而上(LALR)語法分析方法。可以將任何一種程式語言的所有語法翻譯成針對此種語言的 Yacc 語法解析器。但是其生成的程式碼一般都比較晦澀難懂。

    • Lex 和Yacc 可以結合使用。

    • ANTLR 是採用 java 編寫的,基於自頂向下的遞迴下降 LL 演算法實現的語法解析器生成器。SQL解析的結果是生成抽象語法樹 AST(abstract syntax tree)。

2.3 邏輯計劃

AST 會被解析成一個邏輯計劃,包含使用者書寫的資料處理邏輯及順序。
邏輯處理順序,指的是一條 SQL 語句應該如何執行,每一個關鍵字、子句部分在什麼時刻執行。

「分散式技術專題」剖析一個SQL的解析及執行過程

需要注意的是,SQL 的執行順序,並不是按書寫順序從上到下,從左到右執行的。
下面列出了一個標準SQL的實際資料處理順序:

「分散式技術專題」剖析一個SQL的解析及執行過程

可以看出,操作的順序是先選定需要操作的表,之後使用 on 和 where 條件過濾,然後按業務進行分割槽重組,最後進行排序操作。

2.4 RBO 和 CBO最佳化

由於使用者的能力不同,同一個業務書寫出來的SQL指令碼可能千差萬別,這樣會導致邏輯計劃可能不是最優的執行路徑。所以邏輯計劃需要被最佳化。
資料庫一般有兩種查詢最佳化器:

  • RBO: Rule-Based Optimization 基於規則的最佳化器

    • SQL的執行計劃。比如查詢時索引的優先順序大於全表掃描屬於 RBO 最佳化,謂詞下推也屬於 RBO 最佳化。

  • CBO: Cost-Based Optimization 基於代價的最佳化器

    • CBO 會透過根據統計資訊(Statistics)和代價模型(Cost Model)計算各種可能“執行計劃”的“代價”, 即 COST,從中選用 COST 最低的執行方案,作為實際執行方案。

    • IO、網路 IO、CPU 的使用情況。對錶做預分析,就是預先統計表的分佈和資料量,屬於 CBO 最佳化。

2.5  執行計劃

邏輯計劃經過 RBO 和 CBO 最佳化之後,就會生成執行計劃。
分散式資料庫中,執行計劃是可以分散式並行執行的,其任務之間的關係可以看作是一個有向無環圖 DAG。

「分散式技術專題」剖析一個SQL的解析及執行過程

上圖中的執行計劃被拆分成了 4 個子任務,每個任務都可以被提交到一個或者多個節點上執行。

2.6  許可權控制

使用者在提交 SQL 時,是附帶了個人身份認證資訊的,許可權控制會校驗當前使用者是否有 SQL 中對應 DDL/ DCL/ DML/ 等許可權。

2.7  資源排程

許可權稽核透過後,任務將被髮送到各個執行節點的任務佇列上。每個任務需要先申請相應的 CPU 和記憶體資源,準備就緒後,才能真正的執行。
在大資料體量下,CPU 和記憶體資源的消耗是非常巨大的,這也是為什麼大資料量的併發查詢,有時慢的像蝸牛一樣。

2.8  分散式任務執行

前面說過分散式任務之間的關係可以看作是一個有向無環圖 DAG,每一個子任務完成後,都會將結果作為下一個任務的輸入繼續執行,直到完成最頂層的任務。
一般來說,最底層的任務(帶有 TableScan 運算元)都屬於 IO 密集型的,需要從磁碟中讀取所需的資料,中間任務(帶有 Filter 或 Join 運算元)是需要 CPU 進行判斷或者做笛卡爾積操作等大量計算,而一些排序操作則需要大量的記憶體參與。

2.9  返回最終結果

待所有的任務完成並彙總到根節點時,伺服器便將 SQL 的執行結果返回給客戶端。



以上為剖析一個 SQL 的解析及執行過程, 「分散式技術專題」是國產資料庫 Hubble團隊精心整理編輯,專題會持續更新,歡迎大家保持關注。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70026685/viewspace-2934977/,如需轉載,請註明出處,否則將追究法律責任。

相關文章