mysql學習 基礎架構 sql查詢語句的過程

2022-09-20 20:09:07 字數 2672 閱讀 8157

大概來說,mysql可以分成sever層和儲存引擎層兩部分。

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

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

不同的儲存引擎共用乙個 server 層,也就是從聯結器到執行器的部分。

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

連線命令一般是這麼寫的:

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

-p

連線完成後,如果你沒有後續的動作,這個連線就處於空閒狀態,你可以在 show processlist 命令中看到它。文字中這個圖是 show processlist 的結果,其中的 command 列顯示為「sleep」的這一行,就表示現在系統裡面有乙個空閒連線。

客戶端如果太長時間沒動靜,聯結器就會自動將它斷開。這個時間是由引數 wait_timeout 控制的,預設值是 8 小時。

建立連線的過程通常是比較複雜的,所以我建議你在使用中要儘量減少建立連線的動作,也就是盡量使用長連線。

但是,長連線有時候會快速消耗系統資源,導致oom,解決方案如下:

查詢快取

連線建立完成後,你就可以執行 select 語句了。執行邏輯就會來到第二步:查詢快取。

mysql 拿到乙個查詢請求後,會先到查詢快取看看,之前是不是執行過這條語句。

之前執行過的語句及其結果可能會以 key-value 對的形式,被直接快取在記憶體中。key 是查詢的語句,value 是查詢的結果。如果你的查詢能夠直接在這個快取中找到 key,那麼這個 value 就會被直接返回給客戶端。如果語句不在查詢快取中,就會繼續後面的執行階段。執行完成後,執行結果會被存入查詢快取中。

你可以看到,如果查詢命中快取,mysql 不需要執行後面的複雜操作,就可以直接返回結果,這個效率會很高。

但是大多數情況下我會建議你不要使用查詢快取,為什麼呢?因為查詢快取往往弊大於利。

查詢快取的失效非常頻繁,只要有對乙個表的更新,這個表上所有的查詢快取都會被清空。因此很可能你費勁地把結果存起來,還沒使用呢,就被乙個更新全清空了。對於更新壓力大的資料庫來說,查詢快取的命中率會非常低。除非你的業務就是有一張靜態表,很長時間才會更新一次。

比如,乙個系統配置表,那這張表上的查詢才適合使用查詢快取。好在 mysql 也提供了這種「按需使用」的方式。你可以將引數 query_cache_type 設定成 demand,這樣對於預設的 sql 語句都不使用查詢快取。

而對於你確定要使用查詢快取的語句,可以用 sql_cache 顯式指定,像下面這個語句一樣:

mysql>

select sql_cache *

from t where id=

10;

需要注意的是,mysql 8.0 版本直接將查詢快取的整塊功能刪掉了,也就是說 8.0 開始徹底沒有這個功能了。

分析器

分析器先會做「詞法分析」。你輸入的是由多個字串和空格組成的一條 sql 語句,mysql 需要識別出裡面的字串分別是什麼,代表什麼。

做完了這些識別以後,就要做「語法分析」。根據詞法分析的結果,語法分析器會根據語法規則,判斷你輸入的這個 sql 語句是否滿足 mysql 語法。

一般語法錯誤會提示第乙個出現錯誤的位置,所以你要關注的是緊接「use near」的內容。

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

執行器開始執行的時候,要先判斷一下你對這個表 t 有沒有執行查詢的許可權,如果沒有,就會返回沒有許可權的錯誤。

(在工程實現上,如果命中查詢快取,會在查詢快取返回結果的時候,做許可權驗證。查詢也會在優化器之前呼叫 precheck 驗證許可權)。

舉個栗子

select

*from t where id=

10;

比如我們這個例子中的表 t 中,

id 字段沒有索引,那麼執行器的執行流程是這樣的:

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

對於有索引的表,執行的邏輯也差不多。

你會在資料庫的慢查詢日誌中看到乙個 rows_examined 的字段,表示這個語句執行過程中掃瞄了多少行。這個值就是在執行器每次呼叫引擎獲取資料行的時候累加的。

在有些場景下,執行器呼叫一次,在引擎內部則掃瞄了多行,因此引擎掃瞄行數跟 rows_examined 並不是完全相同的。

問答:1、如果表 t 中沒有字段 k,而你執行了這個語句 select * from t where k=1, 那肯定是會報「不存在這個列」的錯誤: 「unknown column 『k』 in 『where clause』」。你覺得這個錯誤是在我們上面提到的哪個階段報出來的呢?

答:分析器

MySql學習(一)mysql基礎架構

可插拔式儲存引擎 檔案系統 客戶端負責發出sql 結構化查詢語言 負責對sql進行進一步處理 management services utillties 了解 提供一些管理工具 connection pool 了解 管理使用者連線,包括下面幾個元件 authentication 授權管理 threa...

MySQL學習筆記(一) MySQL基礎架構

mysql可分為server層和儲存引擎層兩部分 1.1 server層 聯結器 許可權驗證 盡量使用長連線,但是長連線會消耗記憶體,可以定時清理,也可以重新初始化鏈結資源 查快取 一般不用,除非讀多寫少 8.0移除 分析器 詞法分析,語法分析,語法解析 優化器 使用哪個索引 表連線順序 執行器 執...

MySQL學習之SQL基礎

一 sql語句分類 ddl語句 資料定義語句,這些語句定義了不同的資料段 資料庫 表 列 索引等資料庫物件 dml語句 資料操縱語句,用於新增 刪除 更新和查詢資料庫記錄,並檢查資料完整性 dcl語句 資料控制語句,用於控制不同資料段直接的許可和訪問級別的語句,定義了資料庫 表 字段 使用者的訪問許...