存儲引擎、mysql體系結構、mysql查詢機制

Mysql插拔式的存儲引擎

    存儲引擎的介紹:1、插拔式的插件方式 

                                 2、存儲引擎是指定在表之上的,即一個庫存中的每一個表都可以指定專用的存儲引擎。

                                 3、不管採用什麼樣的存儲引擎,都會在數據區 ,產生對應的frm文件(表結構定義描述文件)

    cvs存儲引擎

     特點:

  • 以CSV格式進行數據存儲(逗號隔開,引號)
  • 所有的列必須都是不能爲NULL的
  • 不支持索引(不適合大表,不適合在線處理)
  • 可以對數據文件直接編輯(保存文本文件內容)

   應用場景:

  •    數據的快速導入,導出
  •    表格直接轉換csv

 archive 存儲引擎

    壓縮協議進行數據的存儲,數據存儲爲ARZ文件格式。

特點:

  • 只支持insert和select兩種操作 只允許自增ID列建立索引 行級鎖
  • 不支持事務
  • 數據佔用磁盤少

應用場景:

  • 日誌系統
  • 大量的設備數據採集

Memory存儲引擎

數據都是存儲在內存中,IO效率要比其他引擎高很多
服務重啓數據丟失,內存數據表默認只有16M
特點:

  • 支持hash索引,B tree索引,默認hash(查找複雜度0(1)) 字段長度都是固定長度varchar(32)=char(32)
  • 不支持大數據存儲類型字段如 blob,text
  • 表級鎖

應用場景:

  • 等值查找熱度較高數據
  • 查詢結果內存中的計算,大多數都是採用這種存儲引擎 作爲臨時表存儲需計算的數據

Myisam存儲引擎

Mysql5.5版本之前的默認存儲引擎 較多的系統表也還是使用這個存儲引擎 系統臨時表也會用到Myisam存儲引擎
特點:

  • select count(*) from table 無需進行數據的掃描
  • 數據(MYD)和索引(MYI)分開存儲
  • 表級鎖
  • 不支持事務

Innodb存儲引擎

  • 支持事務ACID
  • 行級鎖
  • 聚集索引(主鍵索引)方式進行數據存儲
  • 支持外鍵關係保證數據完整性

存儲引擎的對比

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客戶端服務器通信

通信方式:

Mysql客戶端與服務端的通信方式是“半雙工”;
全雙工:雙向通信,發送同時也可以接收 半雙工:雙向通信,同時只能接收或者是發送,無法同時做操作 單工:只能單一方向傳送
半雙工通信: 在任何一個時刻,要麼是有服務器向客戶端發送數據,要麼是客戶端向服務端發 送數據,這兩個動作不能同時發生。所以我們無法也無需將一個消息切成小塊進 行傳輸
特點和限制: 客戶端一旦開始發送消息,另一端要接收完整個消息才能響應。 客戶端一旦開始接收數據沒法停下來發送指令。

查詢通信狀態:

對於一個mysql連接,或者說一個線程,時刻都有一個狀態來標識這個連接正在做什麼    
查看命令 show full processlist / show processlist

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%' 命令可查看緩存情況

不會緩存的情況:

1.當查詢語句中有一些不確定的數據時,則不會被緩存。如包含函數NOW(), CURRENT_DATE()等類似的函數,或者用戶自定義的函數,存儲函數,用戶變 量等都不會被緩存
2.當查詢的結果大於query_cache_limit設置的值時,結果不會被緩存
3.對於InnoDB引擎來說,當一個語句在事務中修改了某個表,那麼在這個事務 提交之前,所有與這個表相關的查詢都無法被緩存。因此長時間執行事務, 會大大降低緩存命中率
4,查詢的表是系統表 5,查詢語句不涉及到表

查詢緩存是一個坑?

1.在查詢之前必須先檢查是否命中緩存,浪費計算資源
2.如果這個查詢可以被緩存,那麼執行完成後,MySQL發現查詢緩存中沒有這 個查詢,則會將結果存入查詢緩存,這會帶來額外的系統消耗
3.針對表進行寫入或更新數據時,將對應表的所有緩存都設置失效。 
4.如果查詢緩存很大或者碎片很多時,這個操作可能帶來很大的系統消耗

查詢緩存適用業務場景

以讀爲主的業務,數據生成之後就不常改變的業務
比如門戶類、新聞類、報表類、論壇類等

3、查詢優化處理

查詢優化處理的三個階段:
 解析sql 
    通過lex詞法分析,yacc語法分析將sql語句解析成解析樹 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的優化
   先進行排序,再採用二分查找的方式,時間複雜度爲O(logn)
...
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

  查詢涉及到的表
  直接顯示錶名或者表的別名
  <unionM,N> 由ID爲M,N 查詢union產生的結果 <subqueryN> 由ID爲N查詢生產的結果

type

訪問類型,sql查詢優化中一個很重要的指標,結果值從好到壞依次是: system > const > eq_ref > ref > range > index > ALL

  • system:表只有一行記錄(等於系統表),const類型的特例,基本不會出現,可以忽略不計 
  • const:表示通過索引一次就找到了,const用於比較primary key 或者 unique索引   const是直接按主鍵或唯一鍵讀取。
  • eq_ref:用於聯表查詢的情況,按聯表的主鍵或唯一鍵聯合查詢
  • ref:非唯一性索引掃描,返回匹配某個單獨值的所有行,本質是也是一種索引訪問 
  • range:只檢索給定範圍的行,使用一個索引來選擇行
  • index:Full Index Scan,索引全表掃描,把索引從頭到尾掃一遍 
  • ALL:Full Table Scan,遍歷全表以找到匹配的行

possible_keys、key、rows、filtered

possible_keys:查詢過程中有可能用到的索引
key:實際使用的索引,如果爲NULL,則沒有使用索引
rows:根據表統計信息或者索引選用情況,大致估算出找到所需的記錄所需要讀取的行 數
filtered:它指返回結果的行佔需要讀到的行(rows列的值)的百分比 表示返回結果的行數佔需讀取行數的百分比,filtered的值越大越好

Extra

十分重要的額外信息

1、Using filesort : mysql對數據使用一個外部的文件內容進行了排序,而不是按照表內的索引進行排序讀取
2、Using temporary: 使用臨時表保存中間結果,也就是說mysql在對查詢結果排序時使用了臨時表,常見於order by 或 group by
3、Using index:表示相應的select操作中使用了覆蓋索引(Covering Index),避免了訪問表的數據行,效率高
4、Using where : 使用了where過濾條件
5、select tables optimized away: 基於索引優化MIN/MAX操作或者MyISAM存儲引擎優化COUNT(*)操作,不必等到執行階段在進行計算,查詢執行 計劃生成的階段即可完成優化

4、查詢執行引擎

調用插件式的存儲引擎的原子API的功能進行執行計劃的執行

5、返回客戶端

1、有需要做緩存的,執行緩存操作
2、增量的返回結果: 開始生成第一條結果時,mysql就開始往請求方逐步返回數據 好處: mysql服務器無須保存過多的數據,浪費內存
       用戶體驗好,馬上就拿到了數據

慢sql

如何定位慢sql

1、業務驅動 2、測試驅動 3、慢查詢日誌

慢查詢日誌配置

show variables like 'slow_query_log'  慢查詢日誌是否開啓 默認是關閉的
set global slow_query_log = on        設置開啓
show variables like 'slow_query%'     查詢慢sql 日誌記錄位置
set global slow_query_log_file = '/var/lib/mysql/sql-slow.log'   設置慢sql日誌存儲位置
set global log_queries_not_using_indexes = on  沒有走索引的查詢 全部記錄到慢sql中
set global long_query_time = 0.1 (秒)  超過0.1s的查詢 放入記錄 到慢sql日誌中

慢查詢日誌分析

Time :日誌記錄的時間 
User@Host:執行的用戶及主機
Query_time:查詢耗費時間 
Lock_time 鎖表時間 
Rows_sent 發送給請求方的記錄 條數 
Rows_examined 語句掃描的記錄條數
SET timestamp 語句執行的時間點 
select .... 執行的具體語句

慢查詢日誌分析工具

mysql 再帶工具 : mysqldumpslow --help

-s ORDER 通過什麼來排序

-t NUM  查看多少行

例如:mysqldumpslow -t 10 -s at /var/lib/mysql/gupaoedu-slow.log

其他慢查詢工具:mysqlsla,pt-query-digest

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章