mysql之存儲引擎 體系結構 查詢機制(二)

一 各大存儲引擎介紹

存儲引擎介紹:

1,插拔式的插件方式 ,插拔式的插件方式
2,存儲引擎是指定在表之上的,即一個庫中的每一個表都可 ,存儲引擎是指定在表之上的,即一個庫中的每一個表都可以指定專用的存儲引擎。
3,不管表採用什麼樣的存儲引擎,都會在數據區,產生對應 ,不管表採用什麼樣的存儲引擎,都會在數據區,產生對應的一個 的一個frm文件(表結構定義描述文件)

csv存儲引擎

數據存儲以 數據存儲以CSV文件 文件
特點:不能定義沒有索引、列定義必須爲NOT NULL、不能設置自增列 不適用大表或者數據的在線處理
CSV數據的存儲用,隔開,可直接編輯CSV文件進行數據的編排 數據安全性低
注:編輯之後,要生效使用flush table XXX 命令
應用場景:
數據的快速導出導入
表格直接轉換成 表格直接轉換成CSV

archive存儲引擎

壓縮協議進行數據的存儲

據存儲爲 數據存儲爲ARZ文件格式 文件格式
特點:

  1. 只支持insert和select兩種操作

  2. 只允許自增ID列建立索引

  3. 行級鎖

  4. 不支持事務

  5. 數據佔用磁盤少

應用場景:

  1. 日誌系統
  2. 大量的設備數據採集

memory 存儲引擎

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

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

應用場景:

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

Myisam

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

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

https://mp.weixin.qq.com/s/FUXPXKfKyjxAvMUFHZm9UQ

Innodb

Mysql5.5及以後版本的默認存儲引擎 及以後版本的默認存儲引擎
Key Advantages:

  1. Its DML operations follow the ACID model [事務ACID]
  2. Row-level locking[行級鎖]
  3. InnoDB tables arrange your data on disk to optimize queries
    based on primary keys[聚集索引(主鍵索引)方式進行數據存儲]
  4. To maintain data integrity, InnoDB supports FOREIGN KEY
    constraints[支持外鍵關係保證數據完整性]

https://dev.mysql.com/doc/refman/5.7/en/innodb-introduction.html

對比

https://dev.mysql.com/doc/refman/5.7/en/storage-engines.html

image-20200627112933093

二 理解mysql體系結構

image-20200627105501082

1,Connectors

接入方 支持協議很多

2,Management Serveices & Utilities:

系統管理和控制工具例如:備份恢復,mysql複製集羣等

3,Connection Pool

連接池:管理緩衝用戶連接、用戶名、密碼、權限校驗、線程處理等需要緩存的需求

4,SQL Interface

SQL接口:接受用戶的SQL命令,並且返回用戶需要查詢的結果。比如select from就是調用SQL Interface

5,Parser: 解析器,SQL命令傳遞到解析器的時候會被解析器驗證和解析。解析器是由Lex和YACC實現的。

6,Optimizer: 查詢優化器,SQL語句在查詢之前會使用查詢優化器對查詢進行優化

7,Cache和Buffer(高速緩存區): 查詢緩存,如果查詢緩存有命中的查詢結果,查詢語句就可以直接去查詢緩存中取數據。

8,pluggable storage Engines

插件式存儲引擎。存儲引擎是MySql中具體的與文件打交道的子系統。也是Mysql最具有特色的一個地方。 Mysql的存儲引擎是插件的。

9,file system

文件系統,數據、日誌(redo,undo)、索引、錯誤日誌、查詢記錄、慢查詢等

三 基於查詢執行路徑理解查詢機制

image-20200627113357735

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

不會緩存的情況:

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

爲什麼 mysql 默認關閉了緩存開啓??

  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 的優化
    先進性排序,再採用二分查找的方式

Mysql 的查詢優化器是基於成本計算的原則。他會嘗試各種執行計劃。數據抽樣的方式進行試(隨機的讀取一個 4K 的數據塊進行分析)

執行計劃

image-20200627213148005

id:

select 查詢的序列號,標識執行的順序
1、id相同,執行順序由上至下
2、id不同,如果是子查詢,id的序號會遞增,id值越大優先級越高,越先被執行
3、id相同又不同即兩種情況同時存在,id如果相同,可以認爲是一組,從上往下順序執行;在所有組中,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索引
eq_ref:唯一索引掃描,對於每個索引鍵,表中只有一條記錄與之匹配。常見於主鍵 或 唯一索引掃描
ref:非唯一性索引掃描,返回匹配某個單獨值的所有行,本質是也是一種索引訪問
range:只檢索給定範圍的行,使用一個索引來選擇行
index:Full Index Scan,索引全表掃描,把索引從頭到尾掃一遍
ALL:Full Table Scan,遍歷全表以找到匹配的行

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

  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 (秒)

慢查詢日誌分析:

image-20200627214059913

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

慢查詢日誌分析工具

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

image-20200627214253949

其他工具 :mysqlsla pt-query-digest

點關注不迷路:

image-20200625023509017

微信圖片_20200626001332

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