01 基礎架構 一條SQL查詢語句是如何執行的

2021-09-22 02:19:56 字數 1757 閱讀 7506

目錄概括

聯結器查詢快取

分析器執行器

mysql基本架構示意圖:

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

server層包括聯結器、查詢快取、分析器、優化器、執行器等,涵蓋mysql大多數核心服務功能,以及所有的內建函式(如日期、時間、數學和加密函式等),所有跨引擎的功能都在這一層實現,比如儲存過程、觸發器、檢視等。

儲存引擎層負責資料的儲存很提取。其架構模式是外掛程式式的,支援innodb、myisam、memory等多個儲存引擎。現在最常用的儲存殷勤是innodb,它從mysql5.5.5版本開始成為預設儲存引擎。

第一步,會先連線到資料庫上,這時候接待你的就是聯結器。聯結器負責跟客戶端建立連線、獲取許可權、維持和管理連線。

連線完成後,如果你沒有後續動作,這個連線就處於空閒狀態,可以通過show processlist命令中看到它。sleep這行表示現在系統裡面有乙個空閒連線,如下(這是我使用我本地資料庫的查詢結果):

資料庫中的長連線、短連線。

連線資料庫耗時,建議盡量使用長連線,但是長連線會使得mysql的記憶體漲的特別快,可能會導致異常重啟。解決辦法:1、定期斷開長長連線;2、如果使用的是mysql5.7或者更新版本,可以在需要的時候執行mysql_reset_connection來重新初始化連線資源,這個過程需要重連和重新做許可權驗證,但是會將連線狀態恢復至剛剛建立完成時的狀態。

連線建立完成後,就可以執行select語句了。執行邏輯來到第二部:查詢快取。如果快取存在,直接返回。如果快取不存在,就會繼續執行後面的執行階段,執行完後,執行結果會被存入查詢快取。

但是大多數情況下建議不要使用查詢快取,因為查詢快取往往弊大於利。

查詢快取的失效率非常頻繁,只要有對乙個表的更新,這個表上所有的查詢快取都會被清空。除非靜態表,幾乎不做更新。

mysql也提供了引數可以設定是否使用快取,可以將引數query_cache_type設定成demant,這樣預設都不使用查詢快取。對於確定要使用查詢快取的可以這樣使用:select sql_cache * from t where id=10;

需要注意的是,mysql8.0版本將整個查詢快取功能刪除掉了。

詞法分析、語法分析

先做詞法分析,識別關鍵字、表名、列

然後做語法分析、是否符合mysql語法

優化器經過分析器,mysql就知道你要做什麼了。然後還要經過優化器的處理。

優化器是在表裡面有多個索引的時候,決定使用哪個索引;或者有多表關聯的時候,決定各個表的連線順序。

優化器執行完後,這個語句的執行方案就確定下來了,然後進入執行器階段。

mysql經過分析器知道了你要做什麼,經過優化器知道了怎麼做,於是就進入了執行器階段,開始執行語句。

開始執行的時候,要先判斷你對當前表有沒有執行查詢的許可權,如果沒有就會返回沒有許可權的錯誤。

如果有許可權,就開啟表繼續執行,一行一行的掃瞄表中資料,將符合條件的結果放入結果集中,知道表中最後一行資料,最後將結果集返回給客戶端。

至此,乙個sql查詢語句就執行完了。

問題:為什麼對許可權的檢查不在優化器之前做?

有些時候,sql語句要操作的表不只是sql字面上那些,比如有個觸發器,得在執行器階段才能確定,優化器階段是無能為力的。

一條SQL語句研究

現有 select from t where a in 5,3,2,1,8,9,30.假設 a 是主鍵,in裡面的引數是唯一的。現要求輸出的結果集按照 in 提供的引數順序排序。而不是按照a本身的排序規則排序?另 如果不要求使用臨時表或表變數,那麼又有什麼辦法實現。臨時表方案參卡 create ta...

MySql 一條查詢SQL語句的執行

這個的快取不是指redis,或者mybatis的快取我們常見的快取,其實mysql自帶了快取模組,但是我們幾乎從來沒有用過他,甚至在mysql8.0直接就給去掉了,所以一定有他的侷限性,大家可以查閱一下,但是確實是存在的。如果開啟的話,所以乙個查詢sql先會查詢快取 我們沒有使用快取的話,就會跳過快...

sql語句ding 求一條sql語句

我理解你的問題是每乙個使用者id在乙個部門中所有的許可權,你給的資料好像不詳細,我新增了一些資料,你看看滿足需求不。sql with authority as 2 select 3029 kuid,205 krid,21 kdid from dual union all 3 select 3029 ...