MySQL 查詢語句執行過程淺析

rocketeer發表於2022-01-25

經典的一條語句:

select * from user where id=1

MySQL的大概架構是這樣的。

MySQL

(網圖,侵刪)

聯結器

而當你在程式裡執行上面那條語句時,MySQL首先走到了聯結器,這就類似於下面的命令。

mysql -h$ip -P$port -u$user -p

這條命令相信都用過吧,這是登入資料庫的命令。此時聯結器會做許可權驗證,如果你的使用者名稱錯誤,將會返回Access denied for user

如果正確,聯結器會在許可權表裡面查出你這個賬號擁有的許可權,需要注意的是,之後所有的操作都將依賴此時你登入的賬號。這就意味著,即使你更改了這個使用者的許可權,也必須等到下次登入才會生效。

我們都知道,建立連線通常是比較複雜的,所以很多時候我們都選擇長連線,但是很多時候也會發現使用長連線 mysql佔用的記憶體會越來越大。

這是因為mysql在執行過程中,臨時的記憶體都是管理在連線物件裡面的。這些資源只有在斷開時才會被釋放。

這種情況,可以考慮以下兩種選擇:

1.定期斷開連線。程式裡執行一個佔用大記憶體的查詢後主動斷開。之後再查詢要重連。

2.5.7版本之後有個mysql_reset_connection命令,意思是不需要重連和做許可權驗證,初始化這個連線。

2、查詢快取

連線建立完成後,就可以執行select了,mysql拿到語句後,會先到查詢快取看看 之前是不是執行過這條語句。查詢快取裡面儲存的是類似key-value的形式,如果有執行的話將會直接返回結果,這樣的效率會大大提高。

但是!如果你表更新很頻繁的話,強烈建議不使用查詢快取。因為每次更新,都將重置查詢快取。因此你還沒用,就把費勁存起來的結果清空了,命中率會非常低。

需要注意,mysql8.0已經將查詢快取刪除。

分析器

當MySQL發現並沒有查詢快取後,繼續往下執行,這時走到了分析器。

分析器,顧名思義就是分析你這條sql。首先,mysql會做“詞法分析”,根據你這段sql進行拆分。例如,select是個關鍵字,它會拆分,mysql需要識別出裡面的字元分別是什麼,代表什麼(這就相當於框架中的curd方法,也是做的分析)。

做完了識別後,就會進行“語法分析”,判斷你這條sql是否符合語法規定,如果不符合,會返回語法錯誤。”

You have an error in your SQL syntax

一般我們需要關注的是”use near”後面緊跟著的內容。

優化器

如果一切得當,這時又會走到了”優化器”。“優化器”,就是會判斷你這條sql裡面是否有優化的地方,使用哪個索引,以及使用join時,先連哪張表效率更高

當優化器做完後,這條sql的執行方案就確定下來了,就下來就會進入執行器階段。

執行器

執行器首先會判斷你是否有對這張表的查詢許可權,如果沒有,將會返回錯誤。“select command denied to user”需要注意,查詢快取返回結果前也會判斷是否有許可權。

如果有許可權,執行器會根據表的引擎定義,去呼叫引擎提供的介面。

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

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章