【MySQL原理解析】01. 一条SQL查询语句是如何执行的
這是【MySQL原理解析】的第一篇文章,MySQL我看了很多的書與教程,對其原理有一定的理解,一直想寫一系列的文章來把MySQL的原理給講清楚,一直沒有時間寫,今天算是個開頭吧。萬事開頭難,咱們先破了這個開頭!
MySQL基本架構
我們常說,看一件事不要直接陷入細節,應該先從整體框架與流程上把握住,先從最高的維度理解問題,然后再逐步深入各個模塊。學習MySQL也是一樣,在使用MySQL的過程中,我們最開始都是從一條簡單的查詢語句開始。如在學生表student中按照學生的id來查學生的信息:
select * from student where id = 100;在我們程序員眼里,這就是一條sql語句,執行之后,返回一條結果。這看起來很簡單的過程,實際在MySQL內部,卻是一個非常復雜的過程。今天我們就來把這個過程拆解出來。
下面給出的是MySQL的基本架構示意圖,從中可以看出SQL語句在MySQL的各個功能模塊的執行過程。
MySQL的基本架構可以分為兩大塊,一塊是Server層,一塊是存儲引擎層。
Server層包括連接器、查詢緩存、分析器、優化器、執行器等。涵蓋了MySQL大多數的核心服務功能、以及所有的內置函數,所有跨存儲引擎的功能都在這一層實現,比如存儲過程、觸發器。視圖等。
存儲引擎層負責數據的存儲與提取。其架構模式是插件式的,支持InnoDB、MyISAM、Memmory等多個存儲引擎。最常用的是InnoDB存儲引擎。所以我們的系列文章也主要是以InnoDB存儲引擎為主。
連接器
在客戶端執行上面的查詢語句時,客戶端首先會與服務端建立一個TCP連接,每個客戶端連接都會在服務端進程中擁有一個線程。這個連接的查詢只會在這個單獨的線程中執行,該線程只能輪流在某個CPU中運行。服務器會負責緩存線程,因此不需要為每一個新建的連接創建或者銷毀線程。在連接的過程中還涉及到一些安全校驗與權限校驗等。
連接成功后,如果沒有后續的動作,這個連接就處于空閑的狀態,你可以使用 show processlist 命令來查看線程的各個狀態??蛻舳巳绻L時間沒有動靜,連接器會自動將它斷開。這個時間由參數wait_timeout控制,一般是8小時。如果在連接被斷開后,客戶端再次發送請求的話,就會收到一個錯誤提醒:Lost connection to MySQL server during query。這時候如果還要繼續查詢,就要重新建立連接,然后再執行請求。
在數據庫領域,長連接是連接成功后,如果客戶端有請求,則一直使用同一個連接。短連接則是指每次執行完很少的幾次查詢就斷開連接,下次查詢再重新建立一個。
我們知道TCP建立連接的過程都是非常復雜的,所以應該降低建立連接這個動作,也就是盡量使用長連接。但是全部使用長連接后,有可能也會導致MySQL占用內存特別快,這是因為MySQL在執行的過程中,臨時使用的內存都是管理在連接對象里的。這些臨時使用的內存在斷開連接才會被釋放。所以如果長連接積累下來,可能導致占用內存太大,被系統強行殺掉(OOM),異常重啟。
想要使用長連接,并且還要解決這種OOM問題的話,可以考慮以下兩種方案。
查詢緩存
連接建立成功后,就可以進行select查詢語句了。MySQL拿到一個查詢請求后,會先到查詢緩存看看之前是否有過一樣的查詢,如果有則直接返回結果。如果沒有,才會進行后面的操作。
我們可以看到,查詢緩存如果命中,就不會走后面的分析器、優化器以及存儲引擎提取數據了。但是存儲引擎在最新的MySQL8.0版本中已經不再支持查詢緩存的功能了。為什么呢?
因為查詢緩存失效非常頻繁,只要有對一個表的更新操作,這個表上所的查詢緩存都會被清空。因此很可能你費勁的把緩存建立起來,還沒使用呢,就被一個更新全清空了。對于更新壓力大的數據庫來說,查詢緩存的命中率會非常低。
分析器
解析器說白了就是對你輸入的sql語句的解析,解析成MySQL這個服務端程序能夠識別的代碼。解析的過程中肯定會有判斷sql語句是否正確的語法解析的過程。如果你的語法不對,肯定會報錯。這個過程的原理涉及到詞法分析樹與語法分析樹,較為復雜,這里暫時不深究。
優化器
經過分析器解析出MySQL能夠識別出的代碼后,優化器會對這部分查詢代碼做一系列的算法優化,包括重寫查詢、決定表的讀取順序,以及選擇合適的索引等。用戶可以通過特殊的關鍵字提示(hint)優化器,影響它的決策過程。也可以請求優化器解釋(explain)優化過程的各個因素,使用戶可以知道服務器是如何進行優化決策的。
對于優化器有哪些優化方法來優化查詢,在后面的章節我們會詳細說明。
執行器
MySQL通過分析器知道了你要做什么,通過優化器知道了該如何做,接下來就該真正的開始執行了。
在開始執行的時候,MySQL會再次判斷本次查詢是否對要查詢的表有執行查詢的權限,如果沒有會報錯。如果有權限就打開表繼續執行。打開表的時候,執行器會根據這個表所使用的存儲引擎,選擇對應的存儲引擎接口。
小結
本篇文章主要講解了MySQL的基本架構,MySQL的整體架構還是非常復雜的,我們能夠將MySQL的基本架構搞懂就行。這次主要學會一條查詢語句,大致需要經歷哪些流程,經過了哪些模塊,每一個模塊的細化流程都相當復雜,我們也不必把每一個模塊都搞懂。作為一名后端開發人員,將優化器與存儲引擎層的相關原理搞懂就可以。
在后面的章節,我們會深入學習優化器與存儲引擎相關原理!
總結
以上是生活随笔為你收集整理的【MySQL原理解析】01. 一条SQL查询语句是如何执行的的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: stata15中文乱码_Stata15:
- 下一篇: 中文停用词词表