一條mysql語句的奇幻之旅
我們平常都會用到mysql,但是你真的知道sql語句是怎麼執行的嗎?
比如下面的sql
select * from users;
這條sql語句大致會經過下面的階段:
- 連接器 – 連接器負責建立,管理mysql的連接,你首先要連接到mysql服務器,才能操作mysql。
- 分析器 – 分析器會進行詞法分析和語法分析,語法錯誤會在這個階段被返回。
- 優化器 – 優化器會自動優化我們的sql語句,如果它發現你的sql語句可以進行優化的話。優化器選擇是否使用索引,索引怎麼用。優化器還會選擇更優的執行計劃,最後會輸出一個執行計劃。
- 執行器 – 執行器會根據輸出的執行計劃進行最終的執行。他會調用底層存儲引擎的接口,比如innoDB引擎。
當我們最開始連接數據庫實例的時候,我們要輸入用戶名密碼,這時候連接器會從數據庫的用戶信息中判斷你是否有權限
連接數據庫進行操作,有哪些權限。
如果你輸入的用戶名密碼錯誤或者沒有權限,那麼你會收到下面的報錯信息
Access denied for user 'root'@'localhost'(using password: YES)
這裏我們要搞清楚一個概念,數據庫和數據庫實例,我們使用的都是數據庫實例,用實例來操作數據庫。
連接成功以後開始執行上面的查詢語句。分析器
會分析這個語句的詞法,語法,語義這些信息。通俗來講就是看到select
,update
這些關鍵字,知道你要來幹啥,看看你是不是來搞破壞的,來搗蛋的。看看你是查詢哪個表啊,有什麼條件啊,這些玩意。最後會輸出一個詞法樹。當然了這一步還會分析你的語法有沒有錯誤,比如你把select
打錯試試。打成elect
,會出現下面的報錯信息
You have an error in your SQL syntax: check the maual that corresponds to your MySQL server version for the right syntax to use near 'elect * from users' at line 1
遇到這種sql
語法錯誤,他會告訴你在哪出現了錯誤,其實就是分析器往後分析的時候發現,這不對啊,這不是我要的東西啊,你這偷樑換柱啊。
當這一步的考驗你也通過了,那麼騷年,你離飛昇不遠了。。。
進入優化器階段,優化器接過語法樹,會調整你的語法,比如他覺得你這麼寫它執行起來慢,執行的不爽,那麼他會換個姿勢再來一次。包括你的語法,執行的順序,使用的索引,連表怎麼連。最終優化完成會輸出一個執行計劃。
這個執行計劃我們可以通過explain
關鍵字查看,比如執行下面的語句
explain select * from users;
他會輸出下面的信息。我們可以看到type
這一列是all
。這代表全表掃描。
我們現在在執行另外一個看看。
explain select * from users where id = 1;
看看這個執行結果。可以看到type
這一列是const
。這代表是常量。還有key
這一列是primary
,這代表我們這次使用了主鍵索引。而主鍵索引是聚簇索引,他的page
頁裏面存儲的就是這一行信息,所以只會查詢一次。
上面輸出的執行計劃會最終由執行器來執行,執行器會調用存儲引擎
層的接口。
緩存
其實,在這中間還有一個緩存組件。最開始查詢的時候會先查詢緩存組件的信息,如果沒有緩存,纔會走到分析器,然後往下走。如果命中緩存,那麼直接返回,也就沒後面什麼事情了。