1. 運行機制圖解
2. 運行過程
2.1 建立連接(Connectors & Connection Pool)
通過 客戶端/服務器通信協議
與 MySQL
建立連接。MySQL
客戶端與服務端的通信方式是“ 半雙工 ”
。對于每一個 MySQL
的連接,時刻都有一個線程狀態來標識這個連接正在做什么。
通訊機制:
- 全雙工:能同時發送和接收數據,例如平時打電話。
- 半雙工:指的某一時刻,要么發送數據,要么接收數據,不能同時。例如早期對講機
- 單工:只能發送數據或只能接收數據。例如單行道
線程狀態:
show processlist; //查看用戶正在運行的線程信息,root 用戶能查看所有線程,其他用戶只能看自己的
Id:
線程ID,可以使用 kill xx
殺死當前線程;User:
啟動這個線程的用戶
Host:
發送請求的客戶端的IP
和端口號
db:
當前命令在哪個庫執行
Command:
該線程正在執行的操作命令
-
Create DB:
正在創建庫操作 -
Drop DB:
正在刪除庫操作 -
Execute:
正在執行一個PreparedStatement -
Close Stmt:
正在關閉一個PreparedStatement -
Query:
正在執行一個語句 -
Sleep:
正在等待客戶端發送語句 -
Quit:
正在退出 -
Shutdown:
正在關閉服務器
Time:
表示該線程處于當前狀態的時間,單位是秒
State:
線程狀態
-
Updating:
正在搜索匹配記錄,進行修改 -
Sleeping:
正在等待客戶端發送新請求 -
Starting:
正在執行請求處理 -
Checking table:
正在檢查數據表 -
Closing table:
正在將表中數據刷新到磁盤中 -
Locked:
被其他查詢鎖住了記錄 -
Sending Data:
正在處理Select查詢,同時將結果發送給客戶端
Info:
一般記錄線程執行的語句,默認顯示前100個字符。
show full processlist; // 查看完整的線程執行語句
2.2 查詢緩存(Cache & Buffer)
這是 MySQL
的一個可優化查詢的地方,如果開啟了查詢緩存且在查詢緩存過程中查詢到完全相同的 SQL
語句,則將查詢結果直接返回給客戶端;如果沒有開啟查詢緩存或者沒有查詢到完全相同的 SQL
語句則會由解析器進行語法語義解析,并生成“解析樹”。
緩存
Select
查詢的結果和SQL
語句執行
Select
查詢時,先查詢緩存,判斷是否存在可用的記錄集,要求完全相同(包括參數值),這樣才會匹配緩存數據命中。-
即使開啟查詢緩存,以下
SQL
也不能緩存- 查詢語句使用
SQL_NO_CACHE
- 查詢的結果大于
query_cache_limit
設置 - 查詢中有一些不確定的參數,比如
now()
- 查詢語句使用
show variables like '%query_cache%'; //查看查詢緩存是否啟用,空間大小,限制等
show status like 'Qcache%'; //查看更詳細的緩存參數,可用緩存空間,緩存塊,緩存多少等
2.3 解析器(Parser)
將客戶端發送的 SQL
進行語法解析,生成 "解析樹"
。預處理器根據一些 MySQL
規則進一步檢查 “解析樹”
是否合法,例如這里將檢查數據表和數據列是否存在,還會解析名字和別名,看看它們是否有歧義,最后生成新的 “解析樹”
。
2.4 查詢優化器(Optimizer)
根據 “解析樹”
生成最優的執行計劃。MySQL
使用很多優化策略生成最
優的執行計劃,可以分為兩類:靜態優化(編譯時優化)、動態優化(運行時優化)
。
等價變換策略
-
5 = 5 and a > 5
改成a > 5
-
a < b and a = 5
改成b > 5 and a = 5
- 基于聯合索引,調整條件位置等
優化 count、min、max 等函數
-
InnoDB
引擎min
函數只需要找索引最左邊 -
InnoDB
引擎max
函數只需要找索引最右邊 -
MyISAM
引擎count(*)
,不需要計算,直接返回
提前終止查詢
- 使用了
limit
查詢,獲取limit
所需的數據,就不在繼續遍歷后面數據
in 的優化
-
MySQL
對in
查詢,會先進行排序,再采用二分法查找數據。比如where id in (2,1,3)
,變成where id in (1,2,3)
2.5 查詢執行引擎
負責執行 SQL
語句,此時查詢執行引擎會根據 SQL
語句中表的存儲引擎類型,以及對應的 API 接口
與 底層存儲引擎緩存
或者 物理文件
的交互,得到查詢結果并返回給客戶端。若開啟查詢緩存,這時會將 SQL
語句和結果完整地保存到查詢緩存(Cache&Buffer)
中,以后若有相同的 SQL
語句執行則直接返回結果。
- 如果開啟了查詢緩存,先將查詢結果做緩存操作
- 返回結果過多,采用增量模式返回