MySQL(四)SQL底層執行原理詳解


一、MySQL內部組件結構

  我們簡單的通過一張圖來分析MySQL內部組件結構:

Server層

  主要包括連接器、查詢緩存、分析器、優化器、執行器等,涵蓋 MySQL 的大多數核心服務功能,以及所有的內置函數(如日期、時間、數學和加密函數等),所有跨存儲引擎的功能都在這一層實現,比如存儲過程、觸發器、視圖等。

引擎層

  職能:存儲引擎層負責數據的存儲和提取

  現在最常用的存儲引擎是 InnoDB,它從 MySQL 5.5.5 版本開始成為了默認存儲引擎,即我們在create table時不指定表的存儲引擎類型,默認會設置存儲引擎為InnoDB。 

  PS:引擎層采用的“插拔”的方式:就是說想一些大公司可以針對自己的業務開發自己個性化的存儲引擎,支持 InnoDB、MyISAM、Memory 等多個存儲引擎。

二、詳細分析MySQL內部組件

連接器 

  常見客戶端:navicat,mysql front,jdbc,SQLyog

  職能:客戶端要向mysql發起通信都必須先跟Server端建立通信連接,而建立連接的工作就是有連接器完成的。

  PS:MySQL采用的是長鏈接。長鏈接就是時間持續很長的鏈接,如mysql的鏈接時間一般是8個小時,即一次鏈接可以持續8小時,超過時間就會自動斷開。

客戶端連接方式

命令行連接方式

查看用戶權限

-- 查看user表中用戶的權限
select * from  mysql.user;

  PS:mysql會在每次鏈接的時候再內存中開辟一塊空間用於存放用戶權限的信息,但是當我們區修改user表的權限信息時,是不會實時的更新這個用戶的權限的

  這樣設計的原因:舉個例子,比如在我們修改用戶權限的時候,有一個秒殺的業務場景正在進行,如果要進行用戶權限實時去更新到內存中的話,就必須得把其他業務線程掛起,然后再檢查內存中的用戶權限並更新,這樣就會造成一個Mysql假死的現象,所以mysql修改用戶權限就沒有設計成同步更新內存中的權限。

查詢緩存

mysql > SHOW DATABASES; -- 顯示所有數據庫 

mysql > USE 對應的數據庫名稱; -- 打開數據庫;

mysql > SHOW TABLES; -- 查看當前數據庫的表

功能介紹

  MySQL 拿到一個查詢請求后,會先到查詢緩存看看,之前是不是執行過這條語句。

儲存方式

  類似於map,以SQL為key,查詢結果集為value的形式進行緩存。

  PS:比較雞肋,在8.0的版本已經移除了。

分析器

  如果沒有命中查詢緩存,就要開始真正執行語句了。

  首先,MySQL 需要知道你要做什么,因此需要對 SQL 語句做解析。 分析器先會做“詞法分析”。你輸入的是由多個字符串和空格組成的一條 SQL 語句,MySQL 需要識別出里面的字符串分別是什么,代表什么。

  MySQL 從你輸入的"select"這個關鍵字識別出來,這是一個查詢語句。它也要把字符串“T”識別成“表名 T”,把字符 串“ID”識別成“列 ID”。 做完了這些識別以后,就要做“語法分析”。根據詞法分析的結果,語法分析器會根據語法規則,判斷你輸入的這個 SQL 語句 是否滿足 MySQL 語法。

-- 關鍵詞from寫成了frm,會報錯:You have an error in your SQL syntax; 【有夢想的肥宅】
select * frm t_test;

優化器

  經過了分析器,MySQL 就知道你要做什么了,在開始執行之前,還要先經過優化器的處理。

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

執行器

  開始執行的時候,要先判斷一下登錄賬號對當前表有沒有執行查詢的權限。

  如果沒有,就會返回沒有權限的錯誤,如果有權限,就打開表繼續執行。打開表的時候,執行器就會根據表的引擎定義,去使用這個引擎提供的接口。

bin-log歸檔

  duangduangduang~重點來了哈,學會了這個,一不小心刪庫刪表,暫時不用跑路啦~😂

什么是bin-log呢

  bin-log是Server層實現的二進制日志,他會記錄我們的cud操作。Binlog有以下幾個特點:

  • 1、Binlog在MySQL的Server層實現(引擎共用)
  • 2、Binlog為邏輯日志,記錄的是一條語句的原始邏輯
  • 3、Binlog不限大小,追加寫入,不會覆蓋以前的日志

  PS:開啟bin-log以后的操作記錄才能找回,之前的找不回哈!!!

bin-log格式

  binlog格式有3種statement,row,mixed,推薦使用Row或者Mixed。

  • Statement:記錄的是操作語句【記錄過程】
  • Row:記錄的是操作行【記錄結果】
  • Mixed:以上兩種的綜合

  PS:為什么不用Statement呢? :因為語句的執行結果不確定,比如同一個帶索引的SQL語句,在主庫和從庫執行,可能索引使用的優先級不一樣,對於limit1這種語句可能就會有不一樣的結果,所以不安全,也不夠嚴謹,故一般不使用這種方式。

  PS:為什么也可以用Mixed?  row的話有什么缺點呢?:數據占用空間更大,傳輸壓力更大。

bin-log實操

  MySQL的安裝和配置可以查看:安裝並配置MySQL【windows】

 

 

 

 

三、小問答

Q:大多數情況查詢緩存就是個雞肋,為什么呢?

  原因:查詢緩存的效非常頻繁,只要有對一個表的更新,這個表上所有的查詢緩存都會被清空。 因此很可能你費勁地把結果存起來,還沒使用呢,就被一個更新全清空了。對於更新壓力大的數據庫來說,查詢緩存的命中率 會非常低。

  如何正確使用:靜態表可以使用緩存。比如像是省份表,地市表之類的數據變動幅度比較小的,這個時候緩存就相對來說起作用了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM