mysql架构深入_mysql性能优化2:深入认识mysql体系架构
前言
本文將重點梳理mysql的體系架構,便于了解mysql的實現原理。
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執行流程
以mysql查詢優化流程為例,mysql查詢執行的路徑如下圖所示
下面分步了解下每個步驟
1. mysql 客戶端/服務端通信
半雙工的通信方式
Mysql客戶端與服務端的通信方式是“半雙工”;
半雙工通信: 在任何一個時刻,要么是有 服務器 向客戶端發送數據,要么是客戶端向服務端發送數據,這兩個動作不能同時發生。所以我們無法也無需將一個消息切成小塊進行傳輸。
特點和限制: 客戶端一旦開始發送消息,另一端要接收完整個消息才能響應。 客戶端一旦開始接收數據沒法停下來發送指令。
注:
全雙工:雙向通信,發送同時也可以接收 半雙工:雙向通信,同時只能接收或者是發送,無法同時做操作 單工:只能單一方向傳送
查詢狀態
對于一個mysql連接,或者說一個線程,時刻都有一個狀態來標識這個連接正在做什么
查看命令 show full processlist / show processlist
注: 狀態全集
https://dev.mysql.com/doc/refman/5.7/en/general-thread-states.html
Sleep 線程正在等待客戶端發送數據
Query 連接線程正在執行查詢
Locked 線程正在等待表鎖的釋放
Sorting result 線程正在對結果進行排序
Sending data 向請求端返回數據
可通過kill {id}的方式進行連接的殺掉
2. 查詢緩存
工作原理: 緩存SELECT操作的結果集和SQL語句; 新的SELECT語句,先去查詢緩存,判斷是否存在可用的記錄集; 判斷標準: 與緩存的SQL語句,是否完全一樣,區分大小寫 (簡單認為存儲了一個key-value結構,key為sql,value為sql查詢結果集)
query_cache_type
值:0 -– 不啟用查詢緩存,默認值;
值:1 -– 啟用查詢緩存,只要符合查詢緩存的要求,客戶端的查詢語句和記錄集 都可以緩存起來,供其他客戶端使用,加上 SQL_NO_CACHE將不緩存
值:2 -– 啟用查詢緩存,只要查詢語句中添加了參數:SQL_CACHE,且符合查詢 緩存的要求,客戶端的查詢語句和記錄集,則可以緩存起來,供其他客戶端使用
query_cache_size 允許設置query_cache_size的值最小為40K,默認1M,推薦設置 為:64M/128M;
query_cache_limit 限制查詢緩存區最大能緩存的查詢記錄集,默認設置為1M
show status like 'Qcache%' 命令可查看緩存情況
不會緩存的情況
當查詢語句中有一些不確定的數據時,則不會被緩存。如包含函數NOW(), CURRENT_DATE()等類似的函數,或者用戶自定義的函數,存儲函數,用戶變 量等都不會被緩存
.當查詢的結果大于query_cache_limit設置的值時,結果不會被緩存
對于InnoDB引擎來說,當一個語句在事務中修改了某個表,那么在這個事務 提交之前,所有與這個表相關的查詢都無法被緩存。因此長時間執行事務, 會大大降低緩存命中率
查詢的表是系統表
查詢語句不涉及到表
緩存是一個坑嗎?
為什么mysql默認關閉了緩存開啟?
在查詢之前必須先檢查是否命中緩存,浪費計算資源
如果這個查詢可以被緩存,那么執行完成后,MySQL發現查詢緩存中沒有這個查詢,則會將結果存入查詢緩存,這會帶來額外的系統消耗
針對表進行寫入或更新數據時,將對應表的所有緩存都設置失效。
如果查詢緩存很大或者碎片很多時,這個操作可能帶來很大的系統消耗
緩存的適用場景
以讀為主的業務,數據生成之后就不常改變的業務 比如門戶類、新聞類、報表類、論壇類等
3. 查詢優化處理
查詢優化處理的三個階段
解析sql
通過lex詞法分析,yacc語法分析將sql語句解析成解析樹
注:lex詞法分析介紹
https://www.ibm.com/developerworks/cn/linux/sdk/lex/
預處理階段
根據mysql的語法的規則進一步檢查解析樹的合法性,如:檢查數據的表和列是否存在,解析名字和別名的設置。還會進行權限的驗證
查詢優化器
優化器的主要作用就是找到最優的執行計劃
查詢優化器如何找到最優執行計劃
使用等價變化規則 5 = 5 and a > 5 改寫成 a > 5 a < b and a = 5 改寫成 b > 5 and a = 5 基于聯合索引,調整條件位置等
優化count 、min、max等函數 min函數只需找索引最左邊 max函數只需找索引最右邊 myisam引擎count(*)
覆蓋索引掃描
子查詢優化
提前終止查詢 用了limit關鍵字或者使用不存在的條件
IN的優化 先進性排序,再采用二分查找的方式 ...
Mysql的查詢優化器是基于成本計算的原則。他會嘗試各種執行計劃。 數據抽樣的方式進行試驗(隨機的讀取一個4K的數據塊進行分析)
執行計劃
id
select查詢的序列號,標識執行的順序 1、id相同,執行順序由上至下 2、id不同,如果是子查詢,id的序號會遞增,id值越大優先級越高,越先被執行 3、id相同又不同即兩種情況同時存在,id如果相同,可以認為是一組,從上往下順序執行;在所有組中,id值越大,優先級越高,越先執行
select_type
查詢的類型,主要是用于區分普通查詢、聯合查詢、子查詢等
SIMPLE:簡單的select查詢,查詢中不包含子查詢或者union
PRIMARY:查詢中包含子部分,最外層查詢則被標記為primary
SUBQUERY/MATERIALIZED:SUBQUERY表示在select 或 where列表中包含了子查詢
MATERIALIZED表示where 后面in條件的子查詢
UNION:若第二個select出現在union之后,則被標記為union;
UNION RESULT:從union表獲取結果的select
table
查詢涉及到的表 直接顯示表名或者表的別名 由ID為M,N 查詢union產生的結果 由ID為N查詢生產的結果
type
訪問類型,sql查詢優化中一個很重要的指標,結果值從好到壞依次是: system > const > eq_ref > ref > range > index > ALL
system:表只有一行記錄(等于系統表), const類型的特例,基本不會出現,可以忽略不計
const:表示通過索引一次就找到了,const用于比較primary key 或者 unique索引
eq_ref:唯一索引掃描,對于每個索引鍵,表中只有一條記錄與之匹配。常見于主鍵 或 唯一索引掃描
ref:非唯一性索引掃描,返回匹配某個單獨值的所有行,本質是也是一種索引訪問
range:只檢索給定范圍的行,使用一個索引來選擇行
index:Full Index Scan,索引全表掃描,把索引從頭到尾掃一遍
ALL:Full Table Scan,遍歷全表以找到匹配的行
Extra
十分重要的額外信息
Using filesort : mysql對數據使用一個外部的文件內容進行了排序,而不是按照表內的索引進行排序讀取
Using temporary: 使用臨時表保存中間結果,也就是說mysql在對查詢結果排序時使用了臨時表,常見于order by 或 group by
Using index: 表示相應的select操作中使用了覆蓋索引(Covering Index),避免了訪問表的數據行,效率高
Using where : 使用了where過濾條件
select tables optimized away: 基于索引優化MIN/MAX操作或者MyISAM存儲引擎優化COUNT(*)操作,不必等到執行階段在進行計算,查詢執行計劃生成的階段即可完成優化
其他
possible_keys: 查詢過程中有可能用到的索引
key: 實際使用的索引,如果為NULL,則沒有使用索引
rows: 根據表統計信息或者索引選用情況,大致估算出找到所需的記錄所需要讀取的行數
filtered: 它指返回結果的行占需要讀到的行(rows列的值)的百分比,表示返回結果的行數占需讀取行數的百分比,filtered的值越大越好
4. 查詢執行引擎
調用插件式的存儲引擎的原子API的功能進行執行計劃的執行
5. 返回客戶端
1、有需要做緩存的,執行緩存操作
2、增量的返回結果:開始生成第一條結果時,mysql就開始往請求方逐步返回數據,這樣做有如下兩個 好處:
mysql服務器無須保存過多的數據,浪費內存
用戶體驗好,馬上就拿到了數據
如何定位慢sql
什么時候需要考慮慢sql
1、業務驅動
2、測試驅動
3、慢查詢日志
慢查詢日志配置
show variables like 'slow_query_log' set global slow_query_log = on set global slow_query_log_file = '/var/lib/mysql/gupaoedu-slow.log' set global log_queries_not_using_indexes = on set global long_query_time = 0.1 (秒)
慢查詢日志分析
Time :日志記錄的時間
Use r@Host:執行的用戶及主機
Query_time:查詢耗費時間
Lock_time 鎖表時間 Rows_sent 發送給請求方的記錄 條數
Rows_examined 語句掃描的記錄條數
SET timestamp 語句執行的時間點
select .... 執行的具體語句
慢查詢日志分析工具
mysqldumpslow -t 10 -s at /var/lib/mysql/gupaoedu-slow.log
其他工具 mysqlsla pt-query-digest
總結
本文重點介紹了mysql的體系架構,從中可以了解到一條sql的執行路徑:1.建立連接--> 2.查詢緩存-->3.查詢優化處理(解析,預處理,優化器)--> 4.查詢執行引擎--> 5.返回處理結果 這些都是mysql的內部處理,理解此流程有助于理解mysql的實現原理。
下一篇將重點梳理下mysql中的各種執行引擎。
總結
以上是生活随笔為你收集整理的mysql架构深入_mysql性能优化2:深入认识mysql体系架构的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 1的阶乘之和_1-20的阶乘之
- 下一篇: 计算机原理转移指令题,转移指令计算机原理