SQL語句在MySQL的執(zhí)行過程詳解
MySQL基礎(chǔ)架構(gòu)
先對MySQL的一些基礎(chǔ)組件進行簡單的介紹
- 1.連接器:身份認證和權(quán)限相關(guān)。
- 2.查詢緩存:執(zhí)行查詢語句時,會先查詢緩存(MySQL8.0版本后移除)。
- 3.分析器:詞法分析和語法分析,詞法分析即對一條SQL語句中的關(guān)鍵字進行提取,如select、insert、update、表名、字段名等等,語法分析即查看SQL語句是否有語法錯誤。
- 4.優(yōu)化器:根據(jù)MySQL內(nèi)部的優(yōu)化算法按照最優(yōu)方案執(zhí)行SQL。
- 5.執(zhí)行器:執(zhí)行語句,然后從存儲引擎返回數(shù)據(jù)。
MySQL主要分為server層和存儲引擎層。
- server層:包含連接器、查詢緩存、分析器、優(yōu)化器、執(zhí)行器等,所有跨存儲引擎的功能都在這一層實現(xiàn),比如存儲過程、觸發(fā)器、視圖、函數(shù)等等,還有一個MySQL通用日志binlog日志模塊。
- 存儲引擎層:主要負責數(shù)據(jù)的讀取和存儲采用可以替換的插件式架構(gòu),支持InnoDB、MyISAM、Memory等存儲引擎,其中InnoDB引擎有自帶的日志模塊redo log,現(xiàn)在最常用的存儲引擎是InnoDB,從MySQL5.5之后就是MySQL的默認引擎。
說了這么多,那么SQL語句到底在MySQL中是怎么執(zhí)行的呢?
SQL語句分析分為查詢語句和更新語句。
查詢語句
select * from tb_student A where A.age='18' and A.name=' 張三 ';
結(jié)合上面的說明,我們來結(jié)合這條查詢語句分析一下執(zhí)行過程:
先查詢該語句是否有權(quán)限,如果沒有權(quán)限直接報錯,如果有權(quán)限,在MySQL8.0版本前會查詢緩存,以這條SQL語句為key看是否命中緩存,命中直接返回緩存,沒有命中執(zhí)行下一步。
通過分析器提取該SQL語句中的關(guān)鍵字,如select、from、表名tb_student、查詢的列、等等,然后判斷這個SQL語句是否有錯誤,比如關(guān)鍵字是否拼寫錯誤,沒有錯誤執(zhí)行下一步。
接下來就是優(yōu)化器確定執(zhí)行方案,上面SQL語句有兩種執(zhí)行方案,a先查詢年齡為18,然后查詢name為張三的數(shù)據(jù),b先查詢name為張三,然后查詢age為18的數(shù)據(jù),優(yōu)化器會根據(jù)內(nèi)部的優(yōu)化算法進行選擇執(zhí)行效率最高的一個方案,確定執(zhí)行計劃后開始執(zhí)行語句。
進行權(quán)限校驗,沒有權(quán)限直接返回錯誤信息,如果有權(quán)限就會調(diào)用數(shù)據(jù)庫引擎接口,返回引擎的執(zhí)行結(jié)果。
更新語句
update tb_student A set A.age='19' where A.name=' 張三 ';
執(zhí)行更新語句不同的是要進行日志記錄了,這時候就要引進日志模塊了,MySQL自帶的日志是binlog日志,所有存儲引擎都可以使用,InnoDB引擎有redo log日志,我們就以InnoDB引擎來分析一下這條更新語句的執(zhí)行過程:
先查詢出張三這一條數(shù)據(jù),不會走查詢緩存,因為更新語句會導致與該表相關(guān)的查詢緩存失效。
拿到數(shù)據(jù)后將age改為19,然后調(diào)用引擎API接口,寫入這一行數(shù)據(jù),InnoDB引擎把數(shù)據(jù)保存在內(nèi)存,同時記錄redo log,此時redo log狀態(tài)為prepare,并告訴執(zhí)行器,執(zhí)行完成,隨時可以提交。
執(zhí)行器接收通知后,記錄binlog,并提交reod log。
肯定有人疑惑,這里為什么要用兩個日志記錄,不能用一個日志記錄嗎?
主要原因如下:
功能不同:
redo log
:是InnoDB特有的日志,用于保證事務(wù)的持久性。在數(shù)據(jù)庫發(fā)生崩潰時,通過redo log可以將未持久化到磁盤的數(shù)據(jù)頁恢復到內(nèi)存,從而實現(xiàn)事務(wù)的持久化。binlog
:是MySQL server層的日志,主要用于記錄數(shù)據(jù)庫所有的變更操作,用于數(shù)據(jù)恢復、主從復制等。
恢復需求不同:
redo log
:在數(shù)據(jù)庫崩潰時,能讓數(shù)據(jù)庫恢復到崩潰前的一致狀態(tài),確保已提交的事務(wù)不會丟失。binlog
:binlog日志主要進行從某個位置或某個時間點恢復到另一個位置和時間點的恢復。
總結(jié)
只用redo log或binlog無法同時滿足以上的功能和恢復需求,所以要同時使用redo log和binlog。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
關(guān)于Mysql插入中文字符報錯ERROR 1366(HY000)的解決方法
這篇文章主要介紹了關(guān)于Mysql插入中文字符報錯ERROR 1366(HY000)的解決方法,在我們?nèi)粘J褂胢ysql的過程中會經(jīng)常遇到各種報錯,今天我們就來看一下ERROR 1366報錯的解決方法吧2023-07-07Mysql基礎(chǔ)學習之LAG與LEAD開窗函數(shù)
lead和lag是在SQL中用于創(chuàng)建窗口函數(shù)的兩個常用函數(shù),這篇文章主要給大家介紹了關(guān)于Mysql基礎(chǔ)學習之LAG與LEAD開窗函數(shù)的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2023-11-11Mysql以utf8存儲gbk輸出的實現(xiàn)方法提供
Mysql以utf8存儲gbk輸出的實現(xiàn)方法提供...2007-11-11mysql 5.7.21解壓版安裝配置方法圖文教程(win10)
這篇文章主要為大家詳細介紹了win10下mysql 5.7.21解壓版安裝配置方法圖文教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-02-02