MySQL相關(一)- 一條查詢語句是如何執行的

前言

學習一個新知識最好的方式就是上官網,因此我先把官網貼出來 MySQL官網 (點擊查閱),若是你們有想了解我沒有說到的東西能夠直接上官網看哈~目前 MySQL 最新大版本爲8.0,可是鑑於目前應用比較多的仍是 5.7,因此今天在這裏仍是針對 5.7 來作討論。php

看了官網關於 MySQL 的介紹以後,我發現一個有趣的事情。在我身邊的同事,不少都是把 MySQL 讀錯了,固然,也是由於你們已經約定俗成了,因此我賣的關子是,MySQL 你們通常會都成 my sequel,可是在官網上讀法是這樣的[ My Ess Que Ell ],即把 s q l 分開來讀。固然這個不重要啦,這裏只是跟你們嘮嗑一下哈哈~想驗證的夥伴能夠點擊這個What is MySQL? html

在這裏插入圖片描述
下面開始進入正題:

下面是 MySQL 的發展過程,目前的系統基本上都是分佈式微服務的了,因爲支持事務的特性,因此 innodb 爲默認的存儲引擎,也是咱們今天課程的主角。(MyISAM 和 Innodb 的區別在此不作贅述,想了解 MySQL 的引擎可至 MySQL 引擎連接查閱。 mysql

在這裏插入圖片描述
這裏有一張腦圖,想要完整高清圖片能夠到微信個人公衆號下【6曦軒】下回復 MySQL 腦圖獲取:
在這裏插入圖片描述
接下來咱們會以這張腦圖的一些知識點展開來說,可是因爲文章篇幅有限,有些點可能只會一筆帶過,有興趣的小夥伴能夠到個人公衆號下與我留言討論。

咱們今天的重點,在於將 MySQL 語句的執行流程給你們梳理一遍(若是文章哪裏有疏漏的話,盡請你們批評指正)。程序員

正文

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

查詢語句的執行分爲如下幾步:面試

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

查詢緩存

經過以下語句可查看緩存開關狀況(默認關閉): show variables like 'query_cache%';redis

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

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

  1. 查詢緩存的失效特表頻繁,對一個表的更新都會失效這個表全部的查詢緩存,對於更新頻繁的表命中率過低
  2. MySQL 8.0 直接刪除查詢緩存

解析器生成解析樹

  1. 語法解析

語法解析是解析你的語句是否是知足 MySQL 語法標準,若是不對則會 : ERROR 1064 (42000): You have an error in your SQL syntax … 關於錯誤碼在官網有說明json

  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'; 在這一步選擇開銷最小的計劃執行

查詢執行引擎

這裏執行器會先對權限作一個判斷,若是有權限,纔會執行如下步驟,不然跑出權限異常:

  1. 調用 Innodb 引擎接口獲取這個表的第一行,判斷ID是否爲10,若是不是跳過,若是是則存在結果集中;
  2. 引擎執行下一行,重複判斷相同的邏輯,直到最後一行;
  3. 最後將知足結果的結果集返回;
  4. 對於有索引的表也差很少,第一次是調用知足結果的第一行接口, 下來是查找知足結果的下一行接口

查詢數據返回結果

將查詢數據的結果返回給查詢的客戶端,若是有緩存則返回緩存(前面已經說了默認關閉),能夠說就大功告成了哈哈哈哈,真是曲折。

總結

通過上面一系列的梳理,相信你們對 MySQL 查詢語句的流程也有了一個大體的瞭解,下面是針對查詢語句的流程作的一張圖,方便你們記憶理解:

在這裏插入圖片描述

By the way

有問題?能夠給我留言或私聊 有收穫?那就順手點個讚唄~

固然,也能夠到個人公衆號下「6曦軒」, 回覆「學習」,便可領取一份 【Java工程師進階架構師的視頻教程】~ 回覆「面試」,能夠得到: 【本人嘔心瀝血整理的 Java 面試題】 回覆「MySQL腦圖」,能夠得到 *** 【MySQL 知識點梳理高清腦圖】***

在這裏插入圖片描述
因爲我咧,科班出身的程序員,php,Android以及硬件方面都作過,不過最後仍是選擇專一於作 Java,因此有啥問題能夠到公衆號提問討論(技術情感傾訴均可以哈哈哈),看到的話會盡快回復,但願能夠跟你們共同窗習進步,關於服務端架構,Java 核心知識解析,職業生涯,面試總結等文章會不按期堅持推送輸出,歡迎你們關注~~~
相關文章
相關標籤/搜索