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

2021-09-25 10:21:29 字數 3126 閱讀 7888

我們在寫sql的時候crud這些基本的操作想必大家已經是得心應手了,專欄會更傾向於sql優化與執行過程模型的角度重新學習sql,方便大家在做效能優化上更加熟練。

select

*from t where id=

10;

接下來我們來拆解一下這個sql語句,從中就可以看出sql在mysql中各個模組的執行過程。

總體來說,mysql分為了server層儲存引擎層

server層包括了聯結器,查詢快取,分析器,優化器,執行器等等,涵蓋mysql的大多數核心服務功能,以及內建函式,實現了跨儲存功能。如:儲存過程,檢視,觸發器。

而儲存引擎層負責資料的儲存和提取。支援innodb,mmaisam,memory等多個儲存引擎。現在最常用的儲存引擎是innodb,也就是我們mysql的預設儲存引擎。

換句話說,如果不指定哪種儲存引擎,預設都是innodb,如果指定其他種類也沒問題,但訪問方式更不相同,支援的方式也不同。

我們可以從圖中看出,不同的儲存引擎公用乙個server層,也就是從聯結器到執行器。可以先對每個元件的名字有個印象,以下來分別介紹一下:

聯結器

第一步,先連線到這個資料庫上,這時候就是聯結器來接待。聯結器用來進行認證,連線和管理。連線命令一般是這麼寫:

[root@localhost ~]# docker exec -it mysql04 bash

root@8c6e753e3a28:/# mysql -uroot -p

enter password:

welcome to the mysql monitor. commands end with ; or \g.

your mysql connection id is 8

server version: 8.0.15 mysql community server - gpl

oracle is a registered trademark of oracle corporation and/or its

affiliates. other names may be trademarks of their respective

owners.

type 'help;' or '\h' for help. type '\c' to clear the current input statement.

mysql>

這裡是以docker舉例,大家也可以用自己的方式,總之是進行連線了。

連線過程中,mysql是客戶端工具,用來與服務端建立連線。使用tcp協議進行握手,然後聯結器認證身份進行連線。

連線完成之後,進入空閒狀態,可以使用如下命令檢視連線狀態:

然後預設8小時不進行操作,就會自動斷開連線,由wait_timeout控制。

資料庫裡面,長連線是指連線成功後,如果客戶端持續有請求,則一直使用同乙個連線。短連線則是指每次執行完很少的幾次查詢就斷開連線,下次查詢再重新建立乙個。

如同執行緒一樣,建立連線本身是十分複雜的,所以不要頻繁建立連線。盡量使用長連線。

但是如果使用長連線,記憶體就會長得很快,這是因為mysql的執行過程中記憶體會囤積在連線物件,只有斷開連線才會釋放,所以就會oom了。

解決方案:

定期重連

通過執行 mysql_reset_connection來重新初始化連線資源。

2. 查詢快取

連線結束之後來到第二階段,查詢快取。

當我們執行語句,都會從cache裡面找歷史記錄,歷史記錄以kv形式儲存,k 是sql語句,v是執行結果,如果能搜尋到k,就會直接返回v,節省系統資源。

如果語句不在快取,就會正常執行,然後儲存查詢快取。

但是要注意的是,查詢快取本身有很大的弊端

首先是他的失效,你的sql不可能永遠都存在sql中,只要update乙個表,所有cache就會清空,所以要頻繁更新的表,就不能依靠查詢快取。一般靜態表比較適合用查詢快取。

3. 分析器

如果查詢快取失敗,就要真的去執行sql了。首先,mysql會對sql進行解析。

首先識別你輸入的這個字串分別是什麼,代表什麼。

然後找出類似於select update delete insert這樣的語句,判斷你大體是查詢,刪除還是什麼的。

將表名,列名找出,進行轉化,表a就是tablea 列b就是columnb。

然後最後就是語法分析,判斷正誤。

4.優化器

當識別出沒有問題,就會進行優化。

首先找出索引,決定使用哪乙個索引最好,或者多表關聯,會計算出連線順序。

這裡既可以先取出d.dept is null然後再左外連到e表,也可以先關聯,再將不滿足條件的刪除。

最後結果一樣,但是效率不同。

優化器就是用選擇哪個方案最好的。

5. 執行器

當分析器知道要做什麼,優化器想好了該怎麼優化,最後就是執行了。

執行之前先會判斷許可權問題,許可權滿足許可才能繼續執行。

舉例來看:

select

*from mysqltable where number =

1;

然後說一下正常流程:(1) 首先innodb先會用where去迴圈判斷number的條件,滿足就放到結果集,不滿足就跳過繼續遍歷,直到結束。

(2) 然後將結果集返回到客戶端。

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

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

mysql可以分為server層和儲存引擎層兩部分 一條普通的查詢語是怎樣執行並返回結果了 聯結器查詢快取 大多數情況下建議不要使用查詢快取,查詢快取往往弊大於利。查詢快取的失效非常頻繁,只要有對乙個表的更新,這個表上所有的查詢快取都會被清空。分析器優化器 比如你執行下面這樣的語句,這個語句是執行兩...

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

大體來說,mysql分為 server 層和儲存引擎層,server 層有聯結器 分析器 優化器 執行器和查詢快取 其中,客戶端發出請求與聯結器建立連線並獲取許可權,分析器對sql語句做分析並判斷是否正確 優化器決定使用哪個索引,生成執行計畫,決定多表連線中表的連線順序。執行器執行語句,操作儲存引擎...

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

server層包括聯結器 查詢快取 分析器 優化器 執行器等,涵蓋了mysql的大多數核心服務功能以及所有的內建函式,所有跨儲存引擎的功能都在這一層實現,比如儲存過程 觸發器 檢視等。而儲存引擎層負責資料的儲存與提取。其架構模式是外掛程式式的,支援innodb myisam memory等多個儲存引...