MySQL一條查詢語句執行的具體流程


一條查詢語句是如何執行的

 

查詢語句的執行分為以下幾步:

  1. 查詢緩存
  2. 解析器生成解析樹
  3. 預處理再次生成解析樹
  4. 查詢優化器
  5. 查詢執行計划
  6. 查詢執行引擎
  7. 查詢數據返回結果

查詢緩存

通過如下語句可查看緩存開關情況(默認關閉):
show variables like 'query_cache%';

1.MySQL 拿到一個查詢請求后先會在查詢緩存中看看是否執行過此語句,之前執行的語句會以 key-value 的形式緩存在內存中,key 是緩存的語句,value 是查詢的結果
2.如果命中緩存則直接將結果返回,如果沒有命中則繼續執行后面

在 MySQL 中默認是關閉的,官方也建議關閉,將緩存交托給第三方如 redis 處理,為啥:

查詢緩存的失效特表頻繁,對一個表的更新都會失效這個表所有的查詢緩存,對於更新頻繁的表命中率太低
MySQL 8.0 直接刪除查詢緩存

解析器生成解析樹

  1. 語法解析
語法解析是解析你的語句是不是滿足 MySQL 語法標准,如果不對則會 :
ERROR 1064 (42000): You have an error in your SQL syntax … 關於錯誤碼在官網有說明
  1. 詞法解析

    關於解析完生成的解析樹類似下圖,我以’select name from user_info where sex=1 and age>20’為例:

預處理再次生成解析樹

語義解析,在語法及詞法解析完之后,進行預處理之后再次生成解析樹。

查詢優化器

在這一步將前面生成的解析樹優化成一個執行計划。

在這步做的事情主要有:

  1. 選擇最合適的索引;
  2. 選擇表掃還是走索引;
  3. 選擇表關聯順序;
  4. 優化 where 子句;
  5. 排除管理中無用表;
  6. 決定 order by 和 group by 是否走索引;
  7. 嘗試使用 inner join 替換 outer join;
  8. 簡化子查詢,決定結果緩存;
  9. 合並試圖;

順便提一下,optimizer_trace 優化器追蹤器,在 MySQL 中是默認關閉的(畢竟開啟也會消耗性能嘛對吧),可以使用 set 語句修改一下 optimizer_trace的開關,感受一下:
set optimizer_trace='enabled=on '
先查詢優化器追蹤的開關:
show variables like 'optimizer_trace%';

執行完一條語句之后執行下面語句查看優化器追蹤:
select * from information_schema.optimizer_trace\G
可以看到一個 json 類型的字符串,主要是語句優化的三個階段,篇幅有限,這里不展開,對照着看應該可以看懂。

 

查詢執行計划

查詢最后一次查詢的消耗,用以比較開銷:
show status like 'Last_query_cost';
在這一步選擇開銷最小的計划執行

查詢執行引擎

這里執行器會先對權限做一個判斷,如果有權限,才會執行以下步驟,否則跑出權限異常:

調用 Innodb 引擎接口獲取這個表的第一行,判斷ID是否為10,如果不是跳過,如果是則存在結果集中;
引擎執行下一行,重復判斷相同的邏輯,直到最后一行;
最后將滿足結果的結果集返回;
對於有索引的表也差不多,第一次是調用滿足結果的第一行接口, 下來是查找滿足結果的下一行接口

查詢數據返回結果

將查詢數據的結果返回給查詢的客戶端,如果有緩存則返回緩存(前面已經說了默認關閉)。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM