1. 運行機制圖解
2. 運行過程
2.1 建立連接(Connectors & Connection Pool)
通過 客戶端/服務(wù)器通信協(xié)議
與 MySQL
建立連接。MySQL
客戶端與服務(wù)端的通信方式是“ 半雙工 ”
递宅。對于每一個 MySQL
的連接玄货,時刻都有一個線程狀態(tài)來標(biāo)識這個連接正在做什么。
通訊機制:
- 全雙工:能同時發(fā)送和接收數(shù)據(jù),例如平時打電話。
- 半雙工:指的某一時刻称近,要么發(fā)送數(shù)據(jù),要么接收數(shù)據(jù)曹鸠,不能同時煌茬。例如早期對講機
- 單工:只能發(fā)送數(shù)據(jù)或只能接收數(shù)據(jù)。例如單行道
線程狀態(tài):
show processlist; //查看用戶正在運行的線程信息彻桃,root 用戶能查看所有線程,其他用戶只能看自己的
Id:
線程ID晾蜘,可以使用 kill xx
殺死當(dāng)前線程邻眷;User:
啟動這個線程的用戶
Host:
發(fā)送請求的客戶端的IP
和端口號
db:
當(dāng)前命令在哪個庫執(zhí)行
Command:
該線程正在執(zhí)行的操作命令
-
Create DB:
正在創(chuàng)建庫操作 -
Drop DB:
正在刪除庫操作 -
Execute:
正在執(zhí)行一個PreparedStatement -
Close Stmt:
正在關(guān)閉一個PreparedStatement -
Query:
正在執(zhí)行一個語句 -
Sleep:
正在等待客戶端發(fā)送語句 -
Quit:
正在退出 -
Shutdown:
正在關(guān)閉服務(wù)器
Time:
表示該線程處于當(dāng)前狀態(tài)的時間,單位是秒
State:
線程狀態(tài)
-
Updating:
正在搜索匹配記錄剔交,進行修改 -
Sleeping:
正在等待客戶端發(fā)送新請求 -
Starting:
正在執(zhí)行請求處理 -
Checking table:
正在檢查數(shù)據(jù)表 -
Closing table:
正在將表中數(shù)據(jù)刷新到磁盤中 -
Locked:
被其他查詢鎖住了記錄 -
Sending Data:
正在處理Select查詢肆饶,同時將結(jié)果發(fā)送給客戶端
Info:
一般記錄線程執(zhí)行的語句,默認顯示前100個字符岖常。
show full processlist; // 查看完整的線程執(zhí)行語句
2.2 查詢緩存(Cache & Buffer)
這是 MySQL
的一個可優(yōu)化查詢的地方驯镊,如果開啟了查詢緩存且在查詢緩存過程中查詢到完全相同的 SQL
語句,則將查詢結(jié)果直接返回給客戶端竭鞍;如果沒有開啟查詢緩存或者沒有查詢到完全相同的 SQL
語句則會由解析器進行語法語義解析板惑,并生成“解析樹”。
緩存
Select
查詢的結(jié)果和SQL
語句執(zhí)行
Select
查詢時偎快,先查詢緩存冯乘,判斷是否存在可用的記錄集,要求完全相同(包括參數(shù)值)晒夹,這樣才會匹配緩存數(shù)據(jù)命中裆馒。-
即使開啟查詢緩存姊氓,以下
SQL
也不能緩存- 查詢語句使用
SQL_NO_CACHE
- 查詢的結(jié)果大于
query_cache_limit
設(shè)置 - 查詢中有一些不確定的參數(shù),比如
now()
- 查詢語句使用
show variables like '%query_cache%'; //查看查詢緩存是否啟用喷好,空間大小翔横,限制等
show status like 'Qcache%'; //查看更詳細的緩存參數(shù),可用緩存空間梗搅,緩存塊棕孙,緩存多少等
2.3 解析器(Parser)
將客戶端發(fā)送的 SQL
進行語法解析,生成 "解析樹"
些膨。預(yù)處理器根據(jù)一些 MySQL
規(guī)則進一步檢查 “解析樹”
是否合法蟀俊,例如這里將檢查數(shù)據(jù)表和數(shù)據(jù)列是否存在,還會解析名字和別名订雾,看看它們是否有歧義肢预,最后生成新的 “解析樹”
。
2.4 查詢優(yōu)化器(Optimizer)
根據(jù) “解析樹”
生成最優(yōu)的執(zhí)行計劃洼哎。MySQL
使用很多優(yōu)化策略生成最
優(yōu)的執(zhí)行計劃烫映,可以分為兩類:靜態(tài)優(yōu)化(編譯時優(yōu)化)、動態(tài)優(yōu)化(運行時優(yōu)化)
噩峦。
等價變換策略
-
5 = 5 and a > 5
改成a > 5
-
a < b and a = 5
改成b > 5 and a = 5
- 基于聯(lián)合索引锭沟,調(diào)整條件位置等
優(yōu)化 count、min识补、max 等函數(shù)
-
InnoDB
引擎min
函數(shù)只需要找索引最左邊 -
InnoDB
引擎max
函數(shù)只需要找索引最右邊 -
MyISAM
引擎count(*)
族淮,不需要計算,直接返回
提前終止查詢
- 使用了
limit
查詢凭涂,獲取limit
所需的數(shù)據(jù)祝辣,就不在繼續(xù)遍歷后面數(shù)據(jù)
in 的優(yōu)化
-
MySQL
對in
查詢,會先進行排序切油,再采用二分法查找數(shù)據(jù)蝙斜。比如where id in (2,1,3)
,變成where id in (1,2,3)
2.5 查詢執(zhí)行引擎
負責(zé)執(zhí)行 SQL
語句澎胡,此時查詢執(zhí)行引擎會根據(jù) SQL
語句中表的存儲引擎類型孕荠,以及對應(yīng)的 API 接口
與 底層存儲引擎緩存
或者 物理文件
的交互,得到查詢結(jié)果并返回給客戶端攻谁。若開啟查詢緩存稚伍,這時會將 SQL
語句和結(jié)果完整地保存到查詢緩存(Cache&Buffer)
中,以后若有相同的 SQL
語句執(zhí)行則直接返回結(jié)果巢株。
- 如果開啟了查詢緩存槐瑞,先將查詢結(jié)果做緩存操作
- 返回結(jié)果過多,采用增量模式返回