天天看點

mybatis批量更新sql語句_一條查詢或更新SQL語句 在MySQL中是如何被執行的?Mysql是如何執行查詢語句的?MySQL是如何執行更新語句的?

本篇文章将介紹一條SQL語句在 MySQL中是如何執行的,包括MySQL的查詢、更新操作。若想要了解MySQL中SQL語句中各關鍵字的執行順序,可通過跳轉文末文章連結進行閱讀。

mybatis批量更新sql語句_一條查詢或更新SQL語句 在MySQL中是如何被執行的?Mysql是如何執行查詢語句的?MySQL是如何執行更新語句的?

從上圖中可知,MySQL内部大緻分為服務層和存儲引擎層兩部分:

  • 服務層:包含連接配接器、查詢緩存、分析器、優化器、執行器等。涵蓋MySQL的大多數核心服務功能及所有的内置函數(如日期、時間、數學和加密函數等)。所有跨存儲引擎的功能都将在這一層實作,比如存儲過程、觸發器、視圖,函數等,也包括通用的binglog日志子產品。
  • 存儲引擎層:包含資料的存儲和提取。采用可以替換的插件式架構,支援InnoDB、MyISAM、Memory等多個存儲引擎。現在最常用的存儲引擎是InnoDB,自MySQL 5.5.5版本後,InnoDB成為了預設的存儲引擎。
接下來,我們了解一下連接配接器、查詢緩存、分析器、優化器、執行器。
mybatis批量更新sql語句_一條查詢或更新SQL語句 在MySQL中是如何被執行的?Mysql是如何執行查詢語句的?MySQL是如何執行更新語句的?

所有的SQL操作都将使用連接配接器,主要負責使用者登入資料庫時,進行使用者的身份認證,包括校驗使用者的賬戶、密碼、權限等操作。

其中,驗證使用者名和密碼的過程如下:

  1. 若密碼錯誤,則收到"Access denied for user"的錯誤,然後用戶端程式結束執行。
  2. 若賬戶、密碼都正确,連接配接器會到權限表裡面查出使用者擁有的權限。在此之後,整個連接配接裡面的權限判斷邏輯,都将依賴于此時查詢到的權限。

需要注意的是:當管理者對一個正在連接配接的使用者的權限進行修改,并不會影響該使用者的權限。隻有當修改完成後,使用者重新建立的連接配接時,才會使用新的權限。

mybatis批量更新sql語句_一條查詢或更新SQL語句 在MySQL中是如何被執行的?Mysql是如何執行查詢語句的?MySQL是如何執行更新語句的?

連接配接建立成功後,MySQL會先查詢緩存,先校驗該查詢SQL是否執行過,如果之前執行過的語句,那麼該語句的曆史查詢結果以 Key-Value對的形式緩存在記憶體中,Key為查詢語句,Value為查詢結果。如果緩存中Key被命中,就會直接傳回Value給用戶端,如果沒有命中,就會執行後續的操作。同時,當SQL執行完成後,執行結果會被存入查詢緩存中。

在擷取執行緩存查詢結果時,同樣需要校驗使用者的權限。

需要注意的是:在Mysql中進行查詢時并不建議使用緩存,因為對于經常更新的資料來說,每次更新表其相關的全部查詢緩存都會失效,是以緩存的有效時間很短,查詢緩存的命中率會非常低。但對于不經常更新的資料來說,使用緩存還是可以的。在MySQL 8.0 版本中,直接将查詢緩存的整塊功能删掉了。

mybatis批量更新sql語句_一條查詢或更新SQL語句 在MySQL中是如何被執行的?Mysql是如何執行查詢語句的?MySQL是如何執行更新語句的?

若Mysql 沒有命中緩存,那麼就會進入分析器,分析器将對執行的SQL進行詞法分析與文法分析,主要分為如下兩個步驟:

  • 第一步,詞法分析,一條SQL語句由多個字元串組成,詞法分析将提取關鍵字(比如SELECT,WHERE)、表名、字段名、查詢條件等。
  • 第二步,文法分析,判斷輸入的SQL是否正确,是否符合MySQL的文法。

需要注意的是:判斷查詢的字段在表中是否存在,也是在分析器這裡進行。

mybatis批量更新sql語句_一條查詢或更新SQL語句 在MySQL中是如何被執行的?Mysql是如何執行查詢語句的?MySQL是如何執行更新語句的?

經過分析器後,MySQL得知 SQL是做什麼操作的,優化器的作用就是确定它認為的最優的執行方案(有時候實際并不是最優,僅僅是它認為最優),如,當一個表存在多個索引的時,決定使用哪個索引,或者一個語句存在多表關聯(JOIN)時,決定各個表的連接配接順序。

需要注意的是:因為不同的執行方案的執行效率不同,是以這一步主要是對SQL進行邏輯選擇優化。

mybatis批量更新sql語句_一條查詢或更新SQL語句 在MySQL中是如何被執行的?Mysql是如何執行查詢語句的?MySQL是如何執行更新語句的?

MySQL 通過分析器知道了SQL要做什麼,通過優化器知道了SQL該怎麼做。于是進入了執行器階段,開始執行語句,首先執行前會校驗該使用者有沒有權限,如果沒有權限,就會傳回錯誤資訊。如果有權限,就會去調用引擎的接口,傳回接口執行的結果。

Mysql是如何執行查詢語句的?

SQL語句大緻可以分為2類,一種是查詢操作,一種是更新(插入,更新,删除)操作。我們将先分析下查詢語句,語句如下:

mybatis批量更新sql語句_一條查詢或更新SQL語句 在MySQL中是如何被執行的?Mysql是如何執行查詢語句的?MySQL是如何執行更新語句的?

如上SQL,實作查詢學号為9527的數學成績,我們分析下這個語句的執行流程:

step1 連接配接器:先檢查該語句是否有權限,如果沒有權限,直接傳回錯誤資訊,如果有權限,在MySQL 8.0 版本以前,會先查詢緩存,以這條sql語句為key在記憶體中查詢是否有結果,如果有直接緩存,如果沒有,執行下一步。

step2 分析器:通過分析器進行詞法分析,提取SQL語句的關鍵字,比如提取上面這個語句是查詢SELECT、WHERE,提取需要查詢的表名為CourseInfo,提取查詢所有的字段為StudentId、Score,提取查詢條件為 Course= 'Math' 與 StudentId = 9527。

然後判斷在 這個SQL 語句是否有文法錯誤,比如關鍵詞是否正确、各字段是否在CourseInfo種存在等等,如果檢查沒問題就執行下一步。

step3 優化器:接下來就是優化器進行确定執行方案,上面的SQL語句,存在有兩種執行方案:

  • 方案一:先查詢課程為數學的所有學生的成績,然後再查詢其學号為9527的成績。
  • 方案二:先查詢學号為9527的所有科目的成績,然後再查詢其科目為數學的成績。

是以,優化器需根據自己的優化算法選擇自己認為執行效率最高的一個方案(優化器認為不一定是最好)。

step4 執行器:進行權限校驗,如果沒有權限就會傳回錯誤資訊,如果有權限就會調用資料庫引擎接口,傳回引擎的執行結果。

MySQL是如何執行更新語句的?

接下來我們再看一下更新語句如何執行的,SQL語句如下:

mybatis批量更新sql語句_一條查詢或更新SQL語句 在MySQL中是如何被執行的?Mysql是如何執行查詢語句的?MySQL是如何執行更新語句的?

如上SQL,我們更新學号為9527的學生的數學成績為96分。

查詢語句的執行流程,更新語句也是同樣會走一遍。隻不過執行更新語句時,需要記錄日志,于是引入了日志子產品,MySQL 自帶的日志子產品式 binlog(歸檔日志),所有的存儲引擎都可以使用,同時,InnoDB引擎自帶redo log 日志子產品,我們将以InnoDB 引擎模式下,來看更新語句的執行流程,如下:

step1 連接配接器:先檢查該語句是否有權限,如果沒有權限,直接傳回錯誤資訊。

step2 查緩存:在一個表上有更新的時候,跟這個表有關的查詢緩存會失效,是以這條語句就會把表 CourseInfo 上所有緩存結果都清空。這也就是我們一般不建議使用查詢緩存的原因。

step3 分析器:分析器會通過詞法和文法解析知道這是一條更新語句。

step4 優化器:優化器決定要使用 Course 這個索引。

step5 執行器:執行器先查詢到學号為 9527的數學成績記錄,如果有緩存,則會使用緩存的查詢結果。然後拿到查詢的結果,把 Score 改為 96,得到一行新的資料,再調用引擎接口寫入這行新資料,InnoDB 引擎将這行新資料更新到記憶體中,同時将這個更新操作記錄到 redo log 裡面,此時 redo log 處于 prepare 狀态,然後告知執行器執行完成了,随時可以送出事務。執行器收到通知後記錄binlog,然後調用引擎的送出事務接口,InnoDB 引擎把剛剛寫入的 redo log 改成送出 commit 狀态,更新完成。

相關閱讀 : SQL查詢語句的執行順序解析

mybatis批量更新sql語句_一條查詢或更新SQL語句 在MySQL中是如何被執行的?Mysql是如何執行查詢語句的?MySQL是如何執行更新語句的?

繼續閱讀