字體logo設(shè)計在線生成搜索優(yōu)化軟件
文章目錄
- 前言
- 體系結(jié)構(gòu)
- SQL語句的執(zhí)行流程
- 1、連接MySQL
- 2、查詢緩存
- 3、解析SQL語句
- 4、優(yōu)化SQL語句
- 5、執(zhí)行SQL語句
- 總結(jié)
前言
如果你在使用MySQL時只會寫sql語句的,那么你應(yīng)該看一下《MySQL優(yōu)化的底層邏輯》。如果你只了解到sql是如何優(yōu)化的,那么你應(yīng)該通過本文了解一下Mysql的體系結(jié)構(gòu)以及sql語句的執(zhí)行流程。
體系結(jié)構(gòu)
先來看下MySQL的體系結(jié)構(gòu),下圖是在MySQL官方網(wǎng)站上扒下來的,所以有很高的權(quán)威性和準(zhǔn)確性。
通過這張圖,我們可以直觀的看到MySQL的內(nèi)部結(jié)構(gòu),包括連接器、緩存、解析器、優(yōu)化器、存儲引擎以及支持DDL、DML、存儲過程、視圖等功能的SQL接口。接下來,通過一條sql語句的執(zhí)行來深入了解MySQL各個組件功能以及其作用。
SQL語句的執(zhí)行流程
1、連接MySQL
通常我們會編寫sql語句通過某個客戶端來執(zhí)行并且接受執(zhí)行結(jié)果,比如命令行、JDBC、navicat。但是在執(zhí)行前肯定需要先和MySQL服務(wù)成功建立連接,這個就是「連接器」的工作。
這里通過命令行的方式MySQL服務(wù)建立連接,命令如下:
mysql -h127.0.0.1 -uroot -p
命令連接的是本地的MySQL服務(wù),在輸入密碼后,連接器會驗證用戶和密碼,如果驗證失敗會給客戶端響應(yīng)拒絕訪問的信息。
驗證成功后,連接器會與該客戶端成功建立連接并且讀取該用戶的權(quán)限,用戶之后的操作都會基于權(quán)限進(jìn)行控制。
那么用戶名和密碼以及權(quán)限在哪存儲呢?
在MySQL中,除了開發(fā)人員創(chuàng)建的業(yè)務(wù)庫,還有支撐自己運(yùn)行的系統(tǒng)庫,包括mysql、sys、perfermance_schema、information_schema,用戶信息就存儲在mysql這個庫。
當(dāng)然,MySQL的連接數(shù)也是有限制的,這個可以通過max_connections
參數(shù)控制。
MySQL [mysql]> show variables like 'max_connections';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 1215 |
+-----------------+-------+
也可以通過 show processlist
查看當(dāng)前連接的客戶端。
MySQL [mysql]> show processlist;
+------+------+-----------------+-------+---------+------+----------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+------+------+-----------------+-------+---------+------+----------+------------------+
| 1156 | root | 127.0.0.1:61223 | mysql | Query | 0 | starting | show processlist |
+------+------+-----------------+-------+---------+------+----------+------------------+
2、查詢緩存
當(dāng)成功建立連接后,客戶端就可以向MySQL服務(wù)發(fā)送sql語句了,「SQL接口」就像我們寫的Controller一樣會接收到sql語句,如果是 select
語句,將會去「緩存」中檢索結(jié)果響應(yīng)給客戶端。
有些博客的說法是在解析后才查詢緩存,這種說法是不嚴(yán)謹(jǐn)?shù)?#xff0c;這里拋出官方的說明“如果收到相同的語句,服務(wù)器將從查詢緩存中檢索結(jié)果,而不是解析并再次執(zhí)行該語句”
同時在該說明中可以看到“從MySQL 5.7.20開始,查詢緩存已被棄用,并在MySQL 8.0中被刪除。”這個注釋。按照官方的說法是“緩存只適用于表數(shù)據(jù)不會經(jīng)常變動的場景,如果表數(shù)據(jù)經(jīng)常更新(很明顯大多是這個場景),緩存命中率低下,加上頻繁的維護(hù)緩存,有時候造成的問題比解決的問題還要多,緩存的功能就顯得比較雞肋了。”
3、解析SQL語句
在經(jīng)過緩存后,就由「解析器」開始工作了,解析器的目的是檢查sql語句是否正確以及將sql語句解析成MySQL能夠理解的結(jié)構(gòu),也就是sql語法樹。
像 select1 id from table1
這條sql語句就會在解析時報錯,因為沒有識別到 select
這個關(guān)鍵字(對列名、表名的檢查和驗證是在預(yù)處理階段)。
而像 select id from table1
這條sql語句會被解析成下圖:
如果想了解具體的解析過程可以參考這篇博客
4、優(yōu)化SQL語句
通過解析器生成sql語法樹后就到了「優(yōu)化器」階段了,sql如何執(zhí)行、使不使用索引、使用哪個索引都是在這個階段處理,《MySQL優(yōu)化的底層邏輯》中有寫到,這里不過多贅述。
5、執(zhí)行SQL語句
經(jīng)過「優(yōu)化器」后最終生成一個最優(yōu)的執(zhí)行計劃交給「執(zhí)行器」來執(zhí)行,執(zhí)行器通過調(diào)用「存儲引擎」的接口來獲取數(shù)據(jù),這里先不展開執(zhí)行器與存儲引擎的交互,后面的文章會詳細(xì)闡述一下。
總結(jié)
至此,一條查詢語句的執(zhí)行流程已經(jīng)非常清晰了,同時也認(rèn)識了MySQL的整個體系結(jié)構(gòu)以及各組件的作用。最后用一張圖來收尾本文的核心內(nèi)容并做總結(jié)。
一條查詢SQL語句的執(zhí)行流程:
- 客戶端通過連接器連接MySQL服務(wù)。
- 連接成功后向SQL接口發(fā)送SQL語句請求。
- SQL接口接收到SQL查詢語句會先去緩存查詢,如果命中返回給客戶端,否則交給解析器。
- 解析器在拿到SQL語句后會判斷語法是否正確,正確會生成sql語法樹交給優(yōu)化器,否則報錯給客戶端。
- 優(yōu)化器會根據(jù)sql語法樹生成一個最優(yōu)的執(zhí)行計劃交給執(zhí)行器執(zhí)行。
- 執(zhí)行器拿到執(zhí)行計劃調(diào)用存儲引擎來獲取數(shù)據(jù)響應(yīng)給客戶端。
- 完成!!!