你瞭解mysql是如何執行查詢語句的嘛?

關注微信公衆號程序媛小水,與您一塊兒進步mysql

應該有不少朋友都用過或者據說過數據庫mysql,那麼你清楚mysql對查詢是怎麼運做的嘛? 這篇文章水水就來分享一下mysql是如何執行查詢語句。sql

安裝mysql

首先咱們須要安裝mysql服務器,我是在ubuntu 16.04環境下進行安裝。數據庫

1. 打開終端,更新軟件包列表

$ sudo apt update
複製代碼

2. 安裝mysql

$ sudo apt-get install mysql-server mysql-client
複製代碼

3. mysql腳本進行初始化

$ sudo mysql_secure_installation
複製代碼

執行這條命令時會出現幾回mysql的詢問:修改root帳號的密碼、移除匿名用戶、容許遠程登陸、刪除test數據庫。ubuntu

4. 登陸

mysql -u root -p
複製代碼

5. 建立MySQL數據庫和用戶

$ create database datatest;   # 建立一個名爲datatest的數據庫
mysql> create user`moly`@`*`  identified by'123456';   #建立molly用戶
複製代碼

ps:在建立用戶時 須要注意(我就是踩坑裏了弄了半天)緩存

user`moly`@`*` 須要用 反引號 ` 
複製代碼

可是水水仍是遇到了問題bash

這個時候只要執行這個就能夠啦~

# flush privileges 命令的做用是mysql用戶數據和權限有修改後,不重啓MySQL服務直接生效。
mysql> flush privileges
複製代碼

以後就能夠開心的添加用戶啦~服務器

能夠查看一下咱們建立好的數據庫~微信

mysql> show databases;
複製代碼

查看鏈接的數據庫架構

mysql> show processlist; 
複製代碼

若是不須要能夠進行刪除~ide

mysql> drop databases datatest;
複製代碼

作完了這些準備工做,就要到今天的重點-mysql究竟是怎麼實現語句查詢的呢?

mysql 的基本架構

MySQL 能夠分爲 Server 層存儲引擎層兩部分。

這裏我畫了一個圖,不太好看你們先湊合看哈~

Server 層

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

鏈接器

mysql服務器與客戶端進行鏈接。

本地鏈接 mysql -u 用戶名 -p 密碼

遠程鏈接 mysql -h 遠程ip或域名 -p 端口 -u 用戶名 -p 密碼

mysql -u root -p
複製代碼

雖然密碼也能夠直接跟在 -p 後面寫在命令行中,但可能會致使你的密碼泄露。

鏈接器作了幾個工做?

  1. 將客戶端鏈接到服務端

  2. 獲取到權限等信息

    從權限表裏邊查詢用戶權限並保存在一個變量裏邊以供查詢緩存。

    分析器,執行器在檢查權限的時候使用。

  3. 在鏈接的有效時長內對sql進行處理。

interactive_timeout
wait_timeout
複製代碼

其中 wait_timeout是非交互式鏈接的空閒超時,interactive_timeout是交互式鏈接的空閒超時。

長連接的危害

在鏈接時最好使用長連接,可是MySQL 在執行過程當中臨時使用的內存在鏈接的對象裏,而且這些資源會在鏈接斷開的時候才釋放。 因此會佔用不少內存,達到必定值後有可能被系統強制殺死。

怎麼解決?

有兩個方法:

  1. 按期斷開長鏈接。

    使用一段時間,或者執行過一個佔用內存的查詢操做後,斷開鏈接。

  2. 可使用這個API來從新初始化鏈接資源,將鏈接恢復到剛剛建立完時的狀態。

    mysql_reset_connection
    複製代碼

查詢緩存

拿到語句,先到緩存以(key-value的形式查詢),若是內存中有,則把value返回。你們可能以爲緩存這個東西不錯嗷,能夠減小mysql的工做量。若是以前查詢過直接把值拿過來就能夠了。可是水水卻以爲緩存儘可能別用~你們先別急,往下看。

爲何不用緩存?

查詢緩存的失效很是頻繁,只要有一個表的更新,那麼這個表上全部的查詢緩存都會被清空。這就會引起一個很大的問題,對於更新頻繁的數據庫來講,查詢緩存的命中率會很是低。並且查詢緩存是要從內存中去查詢,命中率低會影響數據庫服務器的性能。所以水水建議若是數據庫表常常更新,最好不要使用緩存。

如何查看緩存?

mysql> show variables like '%query_cache%';
複製代碼

如何設置不使用緩存?

  1. 將參數 query_cache_type 設置成 DEMAND,這樣對於默認的 SQL 語句都不使用查詢緩存。
  2. 也能夠用 SQL_NO_CACHE 指定
mysql> select SQL_NO_CACHE count(host) from user;
複製代碼

分析器

分析器主要負責將命令拆分紅詞來進行詞法和語法分析。

詞法分析:識別關鍵字,表名,列名等等(查看錶,列是否存在)從information schema裏面得到表的信息的。

語法分析:是否知足sql語法

mysql是如何進行語法分析的呢?

答案是經過解析器和預處理器~

  1. mysql經過 關鍵詞 將sql命令語句解析成一棵 「解析樹」

  2. 解析器處理語法和解析查詢,主要有驗證關鍵詞的拼寫和順序是否正確。

    若是語法不正確會出現 "You have an error in your SQL syntax"

  3. 預處理器進一步檢查解析樹是否合法。主要有 檢查表和列是否存在,別名是否被佔用等等。

  4. 預處理器驗證用戶是否有查詢權限。

    若是經過則生成新的解析樹,再提交給優化器。

優化器

決定使用哪一個索引(表中有多個索引) 或者在一個語句有多表關聯(join)的時候,決定各個表的鏈接順序。最後生成執行計劃進入執行器。

執行器

  1. 判斷是否有這個表的查詢權限
res= select_precheck(thd, lex, all_tables, first_table);
複製代碼
  1. 根據指令,經過API調用底層存儲引擎執行。

    mysql實現了一個抽象接口層 handler(sql/handler.h)

有了分析器的權限的檢查爲何還須要執行器的權限檢查??

若是使用觸發器,得在執行器階段才能肯定。 因此分析器工做結束後的precheck是不能對這種運行時涉及到的表進行權限校驗的,因此須要在執行器階段進行權限檢查。 另外正是由於有precheck這個步驟,纔會在報錯時報的是用戶無權限,而不是 k字段不存在,以避免暴露表結構。

相關文章
相關標籤/搜索