mysql體系結構
- Client Connectors
接入方 支持協議很多 - Management Serveices & Utilities
系統管理和控制工具,mysqldump、 mysql複製集羣、分區管理等 - Connection Pool
連接池:管理緩衝用戶連接、用戶名、密碼、權限校驗、線程處理等需要緩存的需求 - SQL Interface
SQL接口:接受用戶的SQL命令,並且返回用戶需要查詢的結果 - Parser 解析器
SQL命令傳遞到解析器的時候會被解析器驗證和解析。解析器是由Lex和YACC實現的 - Optimizer 查詢優化器
SQL語句在查詢之前會使用查詢優化器對查詢進行優化 - Cache和Buffer(高速緩存區) 查詢緩存
如果查詢緩存有命中的查詢結果,查詢語句就可以直接去查詢緩存中取數據 - Pluggable storage Engines
插件式存儲引擎。存儲引擎是MySql中具體的與文件打交道的子系統 - File system
文件系統,數據、日誌(redo,undo)、索引、錯誤日誌、查詢記錄、慢查詢等
mysql查詢優化-查詢執行的路徑
- 查詢執行步驟:
(1) mysql客戶端/服務端通信
(2) 查詢緩存
(3) 查詢優化處理
(4) 查詢執行引擎
(5) 返回客戶端
mysql客戶端/服務端通信
-
Mysql客戶端與服務端的通信方式是“半雙工”
(1) 全雙工:雙向通信,發送同時也可以接收
(2) 半雙工:雙向通信,同時只能接收或者是發送,無法同時做操作
(3) 單工:只能單一方向傳送半雙工通信: 在任何一個時刻,要麼是有服務器向客戶端發送數據,要麼是客戶端向服務端發送數據,這兩個動作不能同時發生。所以我們無法也無需將一個消息切成小塊進行傳輸
-
特點和限制
(1) 客戶端一旦開始發送消息,另一端要接收完整個消息才能響應。
(2) 客戶端一旦開始接收數據沒法停下來發送指令。 -
mysql客戶端/服務端通信-查詢狀態
(1) 對於一個mysql連接,或者說一個線程,時刻都有一個狀態來標識這個連接正在做什麼
(2) 查看命令
(a) Sleep 線程正在等待客戶端發送數據 (b) Query 連接線程正在執行查詢 (c) Locked 線程正在等待表鎖的釋放 (d) Sorting result 線程正在對結果進行排序 (e) Sending data 線程正在向請求端返回數據show full processlist show processlist
(3) 可通過kill {id}的方式進行連接的殺掉
查詢緩存
-
工作原理
(1) 緩存SELECT操作的結果集和SQL語句;
(2) 新的SELECT語句,先去查詢緩存,判斷是否存在可用的記錄集; -
判斷標準
與緩存的SQL語句,是否完全一樣,區分大小寫 (簡單認爲存儲了一個key-value結構,key爲sql,value爲sql查詢結果集) -
查詢緩存配置參數
修改my.cnf文件- query_cache_type
(1) 值:0 -– 不啓用查詢緩存,默認值;
(2) 值:1 -– 啓用查詢緩存,只要符合查詢緩存的要求,客戶端的查詢語句和記錄集都可以緩存起來,供其他客戶端使用,加上 SQL_NO_CACHE將不緩存
(3) 值:2 -– 啓用查詢緩存,只要查詢語句中添加了參數:SQL_CACHE,且符合查詢緩存的要求,客戶端的查詢語句和記錄集,則可以緩存起來,供其他客戶端使用 - query_cache_size
允許設置query_cache_size的值最小爲40K,默認1M,推薦設置 爲:64M/128M;(應該是查詢緩存大小) - query_cache_limit
限制查詢緩存區最大能緩存的查詢記錄集,默認設置爲1M (應該是單次查詢的緩存限制)
- query_cache_type
-
查看緩存情況
show status like 'Qcache%’ //可查看緩存情況
-
查詢緩存-不會緩存的情況
(1) 當查詢語句中有一些不確定的數據時,則不會被緩存。如包含函數NOW(),CURRENT_DATE()等類似的函數,或者用戶自定義的函數,存儲函數,用戶變量等都不會被緩存
(2) 當查詢的結果大於query_cache_limit設置的值時,結果不會被緩存
(3) 對於InnoDB引擎來說,當一個語句在事務中修改了某個表,那麼在這個事務提交之前,所有與這個表相關的查詢都無法被緩存。因此長時間執行事務, 會大大降低緩存命中率
(4) 查詢的表是系統表
(5) 查詢語句不涉及到表 —> select 1; -
查詢緩存的缺點-爲什麼mysql默認關閉了緩存開啓??
(1) 在查詢之前必須先檢查是否命中緩存,浪費計算資源
(2) 如果這個查詢可以被緩存,那麼執行完成後,MySQL發現查詢緩存中沒有這個查詢,則會將結果存入查詢緩存,這會帶來額外的系統消耗
(3) 針對表進行寫入或更新數據時,將對應表的所有緩存都設置失效。
(4) 如果查詢緩存很大或者碎片很多時,這個操作可能帶來很大的系統消耗 -
查詢緩存-使用業務場景
以讀爲主的業務,數據生成之後就不常改變的業務 —> 比如門戶類、新聞類、報表類、論壇類等
查詢優化處理
查詢優化處理的三個階段
-
解析sql
通過lex詞法分析,yacc語法分析將sql語句解析成解析樹 https://www.ibm.com/developerworks/cn/linux/sdk/lex/ -
預處理階段
根據mysql的語法的規則進一步檢查解析樹的合法性,如:檢查數據的表和列是否存在,解析名字和別名的設置。還會進行權限的驗證 -
查詢優化器
優化器的主要作用就是找到最優的執行計劃
查詢優化器如何找到最優執行計劃
Mysql的查詢優化器是基於成本計算的原則。他會嘗試各種執行計劃。數據抽樣的方式進行試驗(隨機的讀取一個4K的數據塊進行分析)
-
使用等價變化規則
(1) 如: 5 = 5 and a > 5 改寫成 a > 5
(2) 如: a < b and a = 5 改寫成 b > 5 and a = 5
(3) 如: 基於聯合索引,調整條件位置
假如: 聯合索引 A,B: 將 where B = 1 and A = 1; 改成 where A = 1 and B = 1; -
優化count 、min、max等函數
(1) min函數只需找索引最左邊
(2) max函數只需找索引最右邊
(3) myisam引擎count(*)
-
覆蓋索引掃描
-
子查詢優化
將子查詢優化成 select * from users where id = 1 -
提前終止查詢
用了limit關鍵字或者使用不存在的條件
-
IN的優化
先進行排序,再採用二分查找的方式
or 是一個一個匹配,in是先排序,然後從2向左或者向右做二分查找
查詢執行引擎
調用插件式的存儲引擎的原子API的功能進行執行計劃的執行
返回客戶端
- 有需要做緩存的,執行緩存操作
- 增量的返回結果
- 開始生成第一條結果時,mysql就開始往請求方逐步返回數據
- 好處: mysql服務器無須保存過多的數據,浪費內存,用戶體驗好,馬上就拿到了數據