Mysql之SQL執(zhí)行流程全面解析
執(zhí)行流程圖解

查詢緩存
Server 如果在查詢緩存中發(fā)現(xiàn)了這條 SQL 語句,就會直接將結(jié)果返回給客戶端;如果沒 有,就進入到解析器階段。
需要說明的是,因為查詢緩存往往效率不高,所以在 MySQL8.0 之后就拋棄了這個功能。
解析器
在解析器中對 SQL 語句進行語法分析、語義分析。

如果沒有命中查詢緩存,就要開始真正執(zhí)行語句了。首先,MySQL需要知道你要做什么,因此需要對SQL語句做解析。SQL語句的分析分為詞法分析與語法分析。
- 分析器先做“ 詞法分析 ”。你輸入的是由多個字符串和空格組成的一條 SQL 語句,MySQL 需要識別出里面 的字符串分別是什么,代表什么。MySQL 從輸入的"select"這個關(guān)鍵字識別出來,這是一個查詢語 句。它也要把字符串“T”識別成“表名 T”,把字符串“ID”識別成“列 ID”。
- 接著,要做“ 語法分析 ”。根據(jù)詞法分析的結(jié)果,語法分析器(比如:Bison)會根據(jù)語法規(guī)則,判斷你輸入的這個 SQL 語句是否 滿足 MySQL 語法 。
經(jīng)過詞法分析和語法分析之后的sql語句是正常的話,會生成一個語法樹

下圖是SQL分詞分析的過程步驟:

優(yōu)化器
在優(yōu)化器中會確定 SQL 語句的執(zhí)行路徑,比如是根據(jù) 全表檢索 ,還是根據(jù) 索引檢索 等。
- 經(jīng)過解釋器,MySQL就知道你要做什么了。在開始執(zhí)行之前,還要先經(jīng)過優(yōu)化器的處理。
- 一條查詢可以有很多種執(zhí)行方式,最后都返回相同的結(jié)果。優(yōu)化器的作用就是找到這其中最好的執(zhí)行計劃。
- 比如:優(yōu)化器是在表里面有多個索引的時候,決定使用哪個索引;或者在一個語句有多表關(guān)聯(lián) (join) 的時候,決定各個表的連接順序,還有表達式簡化、子查詢轉(zhuǎn)為連接、外連接轉(zhuǎn)為內(nèi)連接等
優(yōu)化舉例
select * from test1 join test2 using(ID) where test1.name='zhangwei' and test2.name='mysql高級課程';
- 方案1:可以先從表 test1 里面取出 name='zhangwei'的記錄的 ID 值,再根據(jù) ID 值關(guān)聯(lián)到表 test2,再判斷 test2 里面 name的值是否等于 'mysql高級課程'。
- 方案2:可以先從表 test2 里面取出 name='mysql高級課程' 的記錄的 ID 值,再根據(jù) ID 值關(guān)聯(lián)到 test1,再判斷 test1 里面 name的值是否等于 zhangwei。
這兩種執(zhí)行方法的邏輯結(jié)果是一樣的,但是執(zhí)行的效率會有不同,而優(yōu)化器的作用就是決定選擇使用哪一個方案。優(yōu)化器階段完成后,這個語句的執(zhí)行方案就確定下來了,然后進入執(zhí)行器階段。
優(yōu)化器的兩個階段
- 邏輯查詢優(yōu)化就是通過改變SQL語句的內(nèi)容來使得SQL查詢更高效,同時為物理查詢優(yōu)化提供更多的候選執(zhí)行計劃。通常采用的方式是對SQL語句進行等價變換,對查詢進行重寫,而查詢重寫的數(shù)學(xué)基礎(chǔ)就是關(guān)系代數(shù)。對條件表達式進行等價謂詞重寫、條件簡化,對視圖進行重寫,對子查詢進行優(yōu)化,對連接語義進行了外連接消除、嵌套連接消除等。
- 物理查詢優(yōu)化是基于關(guān)系代數(shù)進行的查詢重寫,而關(guān)系代數(shù)的每一步都對應(yīng)著物理計算,這些物理計算往往存在多種算法,因此需要計算各種物理路徑的代價,從中選擇代價最小的作為執(zhí)行計劃。在這個階段里,對于單表和多表連接的操作,需要高效地使用索引,提升查詢效率。
執(zhí)行器
經(jīng)過前面三個步驟,只是生成了sql的執(zhí)行計劃,由執(zhí)行器來執(zhí)行該sql的執(zhí)行計劃,在執(zhí)行之前需要判斷該用戶是否 具備權(quán)限 。
如果沒有,就會返回權(quán)限錯誤。如果具備權(quán)限,就執(zhí)行 SQL 查詢并返回結(jié)果。
在 MySQL8.0 以下的版本,如果設(shè)置了查詢緩存,這時會將查詢結(jié)果進行緩存。

比如根據(jù)id查詢,并沒有設(shè)置索引的話
調(diào)用 InnoDB 引擎接口取這個表的第一行,判斷 ID 值是不是1,如果不是則跳過,如果是則將這行存在結(jié)果集中;調(diào)用引擎接口取“下一行”,重復(fù)相同的判斷邏輯,直到取到這個表的最后一行。執(zhí)行器將上述遍歷過程中所有滿足條件的行組成的記錄集作為結(jié)果集返回給客戶端。即進行全表掃描遍歷,獲取出所有符合條件的結(jié)果
執(zhí)行流程總結(jié)
SQL 語句在 MySQL 中的流程是: SQL語句→查詢緩存→解析器→優(yōu)化器→執(zhí)行器 。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
避免MySQL中的隱式轉(zhuǎn)換的方法小結(jié)
在 MySQL 中,隱式轉(zhuǎn)換可能導(dǎo)致索引失效、結(jié)果不符合預(yù)期或性能問題,以下是避免隱式轉(zhuǎn)換的具體方法,從表設(shè)計、查詢編寫到配置優(yōu)化,逐步減少隱式轉(zhuǎn)換的發(fā)生,具體操作過程跟隨小編一起看看吧2025-04-04
解決mysql與navicat建立連接出現(xiàn)1251錯誤
在本篇文章里小編給大家整理了一篇關(guān)于mysql與navicat建立連接出現(xiàn)1251錯誤怎么解決的技術(shù)文章,需要的朋友們參考下。2019-08-08
MySql索引原理之聯(lián)合索引與最左前綴原則、覆蓋索引及索引條件下推詳解
本文給大家介紹InnoDB索引機制,包括聯(lián)合索引的最左前綴原則、覆蓋索引優(yōu)化、索引條件下推(ICP)功能及索引失效場景,強調(diào)合理設(shè)計索引可提升查詢效率,避免全表掃描,對mysql最左前綴原則相關(guān)知識感興趣的朋友一起看看吧2025-08-08
MySQL中distinct與group by語句的一些比較及用法講解
這篇文章主要介紹了MySQL中distinct與group by的一些比較及用法講解,二者在查詢操作中的用法有很多相似之處,需要的朋友可以參考下2016-01-01
MySQL分區(qū)建索引以及分區(qū)介紹總結(jié)
當(dāng)mysql一張數(shù)據(jù)表中的數(shù)據(jù)達到一定的量時,在其中查詢某一個數(shù)據(jù),需要花費大量的時間,下面這篇文章主要給大家介紹了關(guān)于MySQL分區(qū)建索引以及分區(qū)介紹的相關(guān)資料,需要的朋友可以參考下2022-04-04
MySQL中實現(xiàn)插入或更新操作(類似Oracle的merge語句)
這篇文章主要介紹了在MySQL中實現(xiàn)插入或更新操作(類似Oracle的merge語句)的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-09-09

