目錄
- 一、從宏觀的角度分析MySQL
- 二、一條SQL執行要經過多少困難?
- 2-1 連接器
- 2-2 查詢緩存
- 2-3 分析器
- 2-4 優化器
- 2-5 執行器
一、從宏觀的角度分析MySQL
首先看一張經典圖片(MySQL邏輯架構圖)

上圖的客戶端可以直接理解為PHP、Java等。接下來,你會看到連接、線程處理。這一部分并不是MySQL所特有的,而且大多數客戶端、服務器都具有類似的結構。
因此,一般而言,MySQL可以分為兩層:Server層和存儲引擎層。
Server層主要包括連接層、查詢緩存、分析器、優化器、執行器等重要模塊組成,這一層還包含了MySQL核心Api部分,比如常用的格式化時間、加密等。
存儲引擎大家都很熟悉,因為在面試中不止一次的問過大家Innodb、Myisam存儲引擎的不同。
所以想過沒有,MySQL為什么會有這么多的存儲引擎呢?
一切技術起源于當下問題,同樣在MySQL中也不例外。
MySQL在存儲引擎這一方面的架構是插件式的,即可以隨意切換不固定,而且MySQL5.5版本存儲引擎已經默認為Innodb。
二、一條SQL執行要經過多少困難?
MySQL詳細架構圖

圖中還有一個熟悉的陌生人查詢緩存模塊,該模塊在MySQL8.0中已不存在。
首先,我們將大致了解當我們執行一條SQL語句時,如何在這個架構圖中運行。
2-1 連接器
mysql -u root -p連接數據庫命令,在執行之后,你將需要輸入密碼。當完成經典的TCP握手之后,連接器就開始發揮作用了。
如果碼錯誤時,則返回Access denied for user ‘root‘@‘localhost‘ (using password: YES,錯誤編碼1045。
如果連接信息均正確,則此時將根據你輸入的用戶訪問權限表來獲取該用戶的權限,此處必須清楚,當你登錄成功后,即使其他人修改了你的權限,在這個連接未斷開之前你的權限是不會發生改變的。
當你連接完成之后,如果你一直不做任何事情,執行show processlist將會看到一個sleep,表示空連接。
那么你知道在MySQL中,如果連接成功后沒有進行任何操作,多久會被自動中斷?
可以執行show variables like 'wait_timeout';用于查看時間。

在MySQL中如果沒有特別說明,那么所有的時間都是以秒為單位的,根據時間轉換可以得知空連接持續8小時。
2-2 查詢緩存
你需要注意的是,MySQL8.0已經被取消了,這個問題不止說了一次了,特別是那些正在使用MySQL8.0以下版本的小伙伴要注意哈!當你切換到8.0時候,遇到這個問題不知道怎么解決。
MySQL8.0為何取消查詢緩存模塊
這個模塊的設計,把查詢語句作為key ,將結果作為value 進行緩存,一旦這個表有更新,之前所有的緩存都會被清除掉。這就像你辛辛苦苦寫的代碼提交之后被別人覆蓋一樣難受。
MySQL8.0以下的版本提供了一個參數query_cache_type = enmand來控制是否要使用查詢緩存,在設置完成后,默認的select語句將不會被緩存。
如果確實可以使用部分場景,那么你可以將sql_cache添加到select關鍵字之后。
如果一條select語句之前被緩存過,那么結果集在這里就會直接返回,而沒有緩存過的select語句就比較辛苦了,還要繼續自己的漫漫長路。
2-3 分析器
MySQL8.0之前,它會在進入分析器之前判斷是否緩存,在MySQL8.0之后,連接器驗證成功后就直接進入分析器。
分析器,根據字面意思來理解就是分析要執行的SQL語句是什么,要做什么。
比如執行select * from user where id = 1
MySQL首先根據select判斷這是一個查詢語句,然后將user識別為表名,id識別為字段名,這個過程被稱為詞法分析。
下一步,需要知道該SQL的語法是否正確,進行語法分析,如果語法不對你就會看到You have an error in your SQL syntax錯誤。通常,將在use near中找到該錯誤。
2-4 優化器
到了這一步,MySQL知道你要做什么,但是要選擇最佳執行方案。
優化器都優化些什么?
舉例來說:多個索引時選擇那個索引、多表關聯時連接順序。
現在你是否想知道,優化器將優化多表關聯的連接順序,那在寫SQL語句時是否就不必考慮連接順序呢?
當然不是,能讓MySQL少做事情就少做,還是一個準則用小表驅動大表。
2-5 執行器
通過要做什么、怎么做后這條SQL語句才會真正的被執行,先進行權限驗證,若沒有權限則直接返回權限錯誤,否則根據表定義的存儲引擎,去使用對應引擎提供的接口。
執行流程圖

上圖包含了正文的所有知識點,也是整個MySQL的大體執行流程圖。
到此這篇關于論一條select語句在MySQL是怎樣執行的的文章就介紹到這了,更多相關select執行MySQL語句內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:- Python基礎之python循環控制語句break/continue詳解
- C語言之初始if語句詳解
- C語言入門篇--學習選擇,if,switch語句以及代碼塊
- 如何用c++表驅動替換if/else和switch/case語句
- C語言中常見的幾種流程控制語句
- 一篇文章帶你了解JavaScript-語句
- Python實現switch/case語句
- C語言進階教程之循環語句缺陷詳析
- C語言控制語句之 循環
- mybatis中sql語句CDATA標簽的用法說明
- JavaScript中三種for循環語句的使用總結(for、for...in、for...of)
- golang switch語句的靈活寫法介紹
- C 語言基礎之C 語言三大語句注意事項