從執行一條sql語句,初窺mysql原理

2021-09-23 02:01:38 字數 2455 閱讀 5897

客戶端傳送一條查詢給伺服器。

連線成功後,會獲取當前連線使用者的許可權。這裡獲取到的許可權對整個連線都有效,一旦連線成功後,如果使用管理員賬號對該使用者更改許可權,當前連線中的擁有的許可權保持不變,只有等到下次重新連線才會更新許可權。

客戶端可能會採取tcp/ip、命名管道或共享記憶體、unix域套接字這幾種方式之一與伺服器進行連線。

每當有乙個客戶端程序連線到伺服器程序時,伺服器程序都會建立乙個執行緒來專門處理與這個客戶端的互動,當該客戶端退出時會與伺服器斷開連線,伺服器並不會立即把與該客戶端互動的執行緒銷毀掉,而是把它快取起來,在另乙個新的客戶端再進行連線時,把這個快取的執行緒分配給該新客戶端。這樣就起到了不頻繁建立和銷毀執行緒的效果,從而節省開銷。從這一點大家也能看出,mysql伺服器會為每乙個連線進來的客戶端分配乙個執行緒,但是執行緒分配的太多了會嚴重影響系統效能,所以我們也需要限制一下可以同時連線到伺服器的客戶端數量。

當我登入乙個的客戶端的時候:使用命令檢視

再來乙個:

如果想檢視mysql的所有執行緒:

select t.thread_id, t.name, t.type, t.processlist_id from performance_schema.threads t ;
當連線建立後,與該客戶端關聯的伺服器執行緒會一直等待客戶端傳送過來的請求,mysql伺服器接收到的請求只是乙個文字訊息,該文字訊息還要經過各種處理。

伺服器先檢查查詢快取,如果命中了快取,則立刻返回儲存在快取中的結果。否則進入下一階段。

需要注意的是,mysql8.0之後已經廢棄了查詢快取。因為這個快取非常容易被清空掉,命中率比較低。只要對錶有乙個更新,這個表上的所有快取就會被清空,因此你剛快取下來的內容,還沒來得及用就被另乙個更新給清空了。所以在8.0之後如果仍然使用查詢快取,那麼可以使用mysql中介軟體proxysql來進行實現。

既然沒有快取,那麼就要進行sql解析了,並生成對應的解析樹。

因為客戶端程式傳送過來的請求只是一段文字而已,所以mysql伺服器程式首先要對這段文字做分析,判斷請求的語法是否正確。

預處理器則根據一些mysql規則進行進一步檢查解析書是否合法(例如檢查資料表和資料列是否存在,還會解析名字和別名,看看它們是否有歧義)

然後從文字中將要查詢的表、各種查詢條件都提取出來放到mysql伺服器內部使用的一些資料結構上來。

語法解析之後,伺服器程式獲得到了需要的資訊,比如要查詢的列是哪些,表是哪個,搜尋條件是什麼等等,但光有這些是不夠的,因為我們寫的mysql語句執行起來效率可能並不是很高,mysql的優化程式會對我們的語句做一些優化,如外連線轉換為內連線、表示式簡化、子查詢轉為連線吧啦吧啦的一堆東西。優化的結果就是生成乙個執行計畫,這個執行計畫表明了應該使用哪些索引進行查詢,表之間的連線順序是啥樣的。我們可以使用explain語句來檢視某個語句的執行計畫。

通常對於同乙個 sql 語句,mysql 內部可能存在多種執行方案。這些方案的執行結果都一樣,但是執行效率不一樣,所以 mysql 在執行之前需要嘗試找出乙個最優的方案來,這就是優化器的主要工作。但是 mysql 也會有選擇錯誤方案的時候,這個當然就是後話了。

mysql根據優化器生成的執行計畫,再呼叫儲存引擎的api來執行查詢。

經過優化器選定了乙個方案後,執行器就按照選定的方案執行 sql 語句。前面我們有講過,在聯結器中會讀取當前使用者的許可權,聯結器中只是獲取許可權而已,並沒有對許可權進行判斷和校驗。

所以在執行器中,在執行語句之前會判斷許可權,如果沒有對應的許可權則會直接返回並提示沒有相關許可權。

這裡你可能會問,為什麼不在聯結器中就直接判斷許可權呢,這裡我覺得可能是因為 mysql 要查詢的表並不一定僅限於 sql 語句中字面上的那些表,有的時候可能需要經過分析器和優化器之後才能確定到底要怎麼執行,所以許可權校驗放在執行器中是有道理的。

注意如果是在前面的查詢快取中查到快取之後,也會在返回結果前做許可權校驗的。

許可權校驗通過之後,就繼續開啟表,呼叫儲存引擎提供的介面去查詢並返回結果集資料。

將結果返回給客戶端。儲存引擎

描述archive

用於資料存檔(行被插入後不能再修改)

blackhole

丟棄寫操作,讀操作會返回空內容

csv用來訪問遠端表

innodb

具備外來鍵支援功能的事務儲存引擎

memory

置於記憶體的表

merge

用來管理多個myisam表構成的表集合

myisam

主要的非事務處理儲存引擎

ndbmysql集群專用儲存引擎

2 2 執行一條SQL語句

對資料庫執行一條sql語句 1 mixed mysqli query mysqli link,string query,int resultmode mysqli store result 1 對於insert,update,delete等不會返回資料的sql語句,在執行沒有錯誤時返回true 2 ...

一條SQL語句如何被執行

select from t where id 10 寫乙個查詢語句不難,但你知道一條sql語句被執行的過程嗎?下圖是mysql的基本架構圖。server層類似中介軟體,主要接受使用者請求,解析請求等。儲存引擎則是底層核心,負責資料的訪問。客戶端要想使用mysql,必須先和mysql建立乙個連線,聯結...

一條SQL語句的執行過程

1.1連線層 提供連線協議 tcp ip,socket 提供驗證 使用者 密碼 ip socket 提供專用連線線程 接收使用者sql,返回結果 通過以下語句可以檢視鏈結執行緒的基本情況 mysql show processlist 1.2sql層 重點 接收上層傳送的sql語句 語法驗證模組 驗證...