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查詢優化-查詢執行的路徑

  • 查詢執行步驟:
    (1) mysql客戶端/服務端通信
    (2) 查詢緩存
    (3) 查詢優化處理
    (4) 查詢執行引擎
    (5) 返回客戶端

mysql客戶端/服務端通信

  • Mysql客戶端與服務端的通信方式是“半雙工”
    (1) 全雙工:雙向通信,發送同時也可以接收
    (2) 半雙工:雙向通信,同時只能接收或者是發送,無法同時做操作
    (3) 單工:只能單一方向傳送

    半雙工通信: 在任何一個時刻,要麼是有服務器向客戶端發送數據,要麼是客戶端向服務端發送數據,這兩個動作不能同時發生。所以我們無法也無需將一個消息切成小塊進行傳輸

  • 特點和限制
    (1) 客戶端一旦開始發送消息,另一端要接收完整個消息才能響應。
    (2) 客戶端一旦開始接收數據沒法停下來發送指令。

  • mysql客戶端/服務端通信-查詢狀態
    (1) 對於一個mysql連接,或者說一個線程,時刻都有一個狀態來標識這個連接正在做什麼
    (2) 查看命令

    show full processlist 
    show processlist
    
    (a) Sleep 線程正在等待客戶端發送數據 (b) Query 連接線程正在執行查詢 (c) Locked 線程正在等待表鎖的釋放 (d) Sorting result 線程正在對結果進行排序 (e) Sending data 線程正在向請求端返回數據

    (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 (應該是單次查詢的緩存限制)
  • 查看緩存情況

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

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

  • 查詢緩存-使用業務場景
    以讀爲主的業務,數據生成之後就不常改變的業務 —> 比如門戶類、新聞類、報表類、論壇類等

查詢優化處理

查詢優化處理的三個階段

  1. 解析sql
    通過lex詞法分析,yacc語法分析將sql語句解析成解析樹 https://www.ibm.com/developerworks/cn/linux/sdk/lex/

  2. 預處理階段
    根據mysql的語法的規則進一步檢查解析樹的合法性,如:檢查數據的表和列是否存在,解析名字和別名的設置。還會進行權限的驗證

  3. 查詢優化器
    優化器的主要作用就是找到最優的執行計劃

查詢優化器如何找到最優執行計劃

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服務器無須保存過多的數據,浪費內存,用戶體驗好,馬上就拿到了數據
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章