1. 程式人生 > 其它 >一條查詢語句的解析和執行過程

一條查詢語句的解析和執行過程

無所不能的程式猿吐出一句魔法[SQL],剎那間,IO 猶如千軍萬馬奔流不息,記憶體 似鯨吸牛飲,海納百川,CPU 更是狂暴著以360%負荷高速運轉,瞬間,一個美妙的身影出現了……
一條SQL的背後,資料庫到底做了什麼,本文將深入淺出的聊一下SQL的解析和執行過程。

一、SQL簡介
SQL是上世紀70年代,基於關係型資料庫發明的一種簡潔的資料操作語言。
SQL按功能可以分為以下三種類型:
• 資料定義語言 DDL
主要用於建立庫表、索引,設定欄位型別,以及指定儲存和壓縮格式等。
• 資料控制語言 DCL
主要用於建立使用者,以及分配角色許可權。
• 資料操縱語言 DML
主要指資料的增刪改查等操作。

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

銀行計算一個人的信用評分及風險等級
券商統計一個年齡段群體的股票喜愛偏好
銀行為客戶群打標籤,制定使用者畫像
• OLTP型別業務
個人在證券市場開戶或購買某隻股票
櫃檯辦理的各種業務
手機APP端使用者的各種操作
每個業務模型,最終都會轉化為一條SQL語句的執行。SQL中包含了你要查詢的實體表名稱,分組、排序欄位,過濾條件等等。
二、SQL的生命週期
生活中,我們做事的步驟一般是先設定目標、然後制定計劃、最後實踐。
資料庫中,一條SQL語句就是要完成的目標;SQL會被編譯器解析生成執行計劃;最後交由執行器去儲存引擎中完成實際的資料操作。
詳細的生命週期可以劃分為建立連線、詞法和語法解析、邏輯計劃、RBO和CBO優化、執行計劃、許可權檢查、資源排程、分散式任務執行、返回最終結果等階段。
1、建立連線
客戶端使用JDBC或ODBC協議,提交一個SQL,到伺服器端。
2、詞法和語法解析
詞法分析是編譯過程的第一個階段,目的是將輸入的各種符號,轉化成相應的識別符號(token),可以被後續階段處理。
詞法分析程式一般稱之為Lexical analyzer或Scanner。


ast
語法分析是編譯過程的一個邏輯階段; 此階段的任務是在詞法分析的基礎上將單詞序列組合成各類語法短語、表示式等。 語法分析程式一般稱之為Parser。
SQL解析的本質是語言轉換,就是把文字程式碼轉換成計算機語言能描述的資料結構。
• 常用SQL編譯工具介紹
lexical compiler ,是一個詞法分析器(scanner)的生成工具, 使用正則表示式來描述各個詞法單元。
Yacc 是一個經典的生成語法分析器的工具,採用自下而上(LALR)語法分析方法。 可以將任何一種程式語言的所有語法翻譯成針對此種語言的 Yacc 語法解析器。但是其生成的程式碼一般都比較晦澀難懂。
Lex 和Yacc 可以結合使用。
ANTLR是採用java編寫的,基於自頂向下的遞迴下降 LL 演算法實現的語法解析器生成器。
SQL解析的結果是生成抽象語法樹 AST(abstract syntax tree)。

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


logical_plan
需要注意的是,SQL的執行順序,並不是按書寫順序從上到下,從左到右執行的。
下面列出了一個標準SQL的實際資料處理順序:
1、 FROM <左表的名字>
2、 ON <join的條件>
3、 <join的型別> <右表的名字>
4、 WHERE <where的條件>
5、 GROUP BY <group by的欄位>
6、 HAVING <having的條件>
7、 SELECT
8、 DISTINCT <要查詢的欄位>
9、 ORDER BY <order by的條件>
10、 LIMIT <limit的數字>
可以看出,操作的順序是先選定需要操作的表,之後使用on和where條件過濾,然後按業務進行分割槽重組,最後進行排序操作。

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優化。

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


exec_plan
上圖中的執行計劃被拆分成了4個子任務,每個任務都可以被提交到一個或者多個節點上執行。
6、許可權控制
使用者在提交SQL時,是附帶了個人身份認證資訊的,許可權控制會校驗當前使用者是否有SQL中對應DDL、DCL、DML等許可權。
7、資源排程
許可權稽核通過後,任務將被髮送到各個執行節點的任務佇列上。每個任務需要先申請相應的CPU和記憶體資源,準備就緒後,才能真正的執行。
在大資料體量下,CPU和記憶體資源的消耗是非常巨大的,這也是為什麼大資料量的併發查詢,有時慢的像蝸牛一樣。
8、分散式任務執行
前面說過分散式任務之間的關係可以看作是一個有向無環圖DAG,每一個子任務完成後,都會將結果作為下一個任務的輸入繼續執行,直到完成最頂層的任務。
一般來說,最底層的任務(帶有TableScan運算元)都屬於IO密集型的,需要從磁碟中讀取所需的資料,中間任務(帶有Filter或Join運算元)是需要CPU進行判斷或者做笛卡爾積操作等大量計算,而一些排序操作則需要大量的記憶體參與。
9、返回最終結果
待所有的任務完成並彙總到根節點時,伺服器便將SQL的執行結果返回給客戶端。
原文連結:https://blog.csdn.net/m0_51698806/article/details/113683382