一條SQL語句,在MySQL中是如何執行的

2022-05-01 21:54:13 字數 2339 閱讀 1758

mysql>

select

*from t where id=

10;

我們看到的只是輸入一條語句,返回乙個結果,卻不知道這條語句在 mysql 內部的執行過程。

mysql 的基本架構示意圖,從中你可以清楚地看到 sql 語句在 mysql 的各個功能模組中的執行過程。

(圖源大體來說,mysql 可以分為 server 層和儲存引擎層兩部分。

也就是說,你執行 create table 建表的時候,如果不指定引擎型別,預設使用的就是 innodb。不過,你也可以通過指定儲存引擎的型別來選擇別的引擎,比如在 create table 語句中使用 engine=memory, 來指定使用記憶體引擎建立表。

由於表經常更新,查詢快取的失效頻繁,查詢快取往往利大於弊。,mysql 8.0 版本開始直接將查詢快取的整塊功能刪掉了。

經過了分析器,mysql 就知道你要做什麼了。在開始執行之前,還要先經過優化器的處理。

優化器是在表裡面有多個索引的時候,決定使用哪個索引;或者在乙個語句有多表關聯(join)的時候,決定各個表的連線順序。比如你執行下面這樣的語句,這個語句是執行兩個表的 join:

mysql>

select

*from t1 join t2 using(id) where t1.c=

10and t2.d=

20;

如果你還有一些疑問,比如優化器是怎麼選擇索引的,有沒有可能選擇錯等等,沒關係,我會在後面的文章中單獨展開說明優化器的內容。

開始執行的時候,要先判斷一下你對這個表 t 有沒有執行查詢的許可權,如果沒有,就會返回沒有許可權的錯誤,如下所示:

mysql>

select

*from t where id=10;

error

1142 (42000): select command denied to

user'b

'@'localhost

'for

table't

'

如果有許可權,就開啟表繼續執行。開啟表的時候,執行器就會根據表的引擎定義,去使用這個引擎提供的介面

比如我們這個例子中的表 t 中,id 字段沒有索引,那麼執行器的執行流程是這樣的:

呼叫 innodb 引擎介面取這個表的第一行,判斷 id 值是不是 10,如果不是則跳過,如果是則將這行存在結果集中;

呼叫引擎介面取「下一行」,重複相同的判斷邏輯,直到取到這個表的最後一行。

執行器將上述遍歷過程中所有滿足條件的行組成的記錄集作為結果集返回給客戶端。

至此,這個語句就執行完成了。

對於有索引的表,執行的邏輯也差不多。第一次呼叫的是「取滿足條件的第一行」這個介面,之後迴圈取「滿足條件的下一行」這個介面,這些介面都是引擎中已經定義好的。

上面是一條查詢sql,再看一條sql語句的執行過程,更新操作:

update tb_student a set a.age='19

'where a.name='張三

';

其實條語句也基本上會沿著上乙個查詢的流程走,只不過執行更新的時候肯定要記錄日誌啦,這就會引入日誌模組了,mysql 自帶的日誌模組式binlog(歸檔日誌),所有的儲存引擎都可以使用,我們常用的innodb引擎還自帶了乙個日誌模組redo log,我們就以innodb模式下來**這個語句的執行流程。流程如下:

這裡肯定有同學會問,為什麼要用兩個日誌模組,用乙個日誌模組不行嗎?這就是之前mysql的模式了,myisam引擎是沒有redo log的,那麼我們知道它是不支援事務的,所以並不是說只用乙個日誌模組不可以,只是innodb引擎就是通過redo log來支援事務的。那麼,又會有同學問,我用兩個日誌模組,但是不要這麼複雜行不行,為什麼redo log 要引入prepare預提交狀態?這裡我們用反證法來說明下為什麼要這麼做?

如果採用redo log 兩階段提交的方式就不一樣了,寫完binglog後,然後再提交redo log就會防止出現上述的問題,從而保證了資料的一致性。那麼問題來了,有沒有乙個極端的情況呢?假設redo log 處於預提交狀態,binglog也已經寫完了,這個時候發生了異常重啟會怎麼樣呢? 這個就要依賴於mysql的處理機制了,mysql的處理過程如下:

這樣就解決了資料一致性的問題。

(圖源1. 

2. 

一條sql語句在mysql中是如何執行的

最近開始在學習mysql相關知識,自己根據學到的知識點,根據自己的理解整理分享出來,本篇文章會分析下乙個sql語句在mysql中的執行流程,包括sql的查詢在mysql內部會怎麼流轉,sql語句的更新是怎麼完成的。下面是mysql的乙個簡要架構圖 mysql主要分為server層和儲存引擎層 ser...

一條SQL語句在mysql中是如何執行的

下圖是 mysql 的乙個簡要架構圖,從下圖你可以很清晰的看到使用者的 sql 語句在 mysql 內部是如何執行的。先簡單介紹一下下圖涉及的一些元件的基本作用幫助大家理解這幅圖,在 1.2 節中會詳細介紹到這些元件的作用。查詢快取 執行查詢語句的時候,會先查詢快取 mysql 8.0 版本後移除,...

一條sql語句在mysql中如何執行的

1.1 mysql 基本架構概覽 下圖是 mysql 的乙個簡要架構圖,從下圖你可以很清晰的看到使用者的 sql 語句在 mysql 內部是如何執行的。先簡單介紹一下下圖涉及的一些元件的基本作用幫助大家理解這幅圖,在 1.2 節中會詳細介紹到這些元件的作用。查詢快取 執行查詢語句的時候,會先查詢快取...