關注微信公衆號程序媛小水,與您一塊兒進步mysql
應該有不少朋友都用過或者據說過數據庫mysql,那麼你清楚mysql對查詢是怎麼運做的嘛? 這篇文章水水就來分享一下mysql是如何執行查詢語句。sql
首先咱們須要安裝mysql服務器,我是在ubuntu 16.04環境下進行安裝。數據庫
$ sudo apt update
複製代碼
$ sudo apt-get install mysql-server mysql-client
複製代碼
$ sudo mysql_secure_installation
複製代碼
執行這條命令時會出現幾回mysql的詢問:修改root帳號的密碼、移除匿名用戶、容許遠程登陸、刪除test數據庫。ubuntu
mysql -u root -p
複製代碼
$ 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 能夠分爲 Server 層和存儲引擎層兩部分。
這裏我畫了一個圖,不太好看你們先湊合看哈~
包括鏈接器、查詢緩存、分析器、優化器、執行器等,涵蓋 MySQL 的大多數核心服務功能,以及全部的內置函數(如日期、時間、數學和加密函數等),全部跨存儲引擎的功能都在這一層實現,好比存儲過程、觸發器、視圖等。 而存儲引擎層負責數據的存儲和提取。
mysql服務器與客戶端進行鏈接。
本地鏈接 mysql -u 用戶名 -p 密碼
遠程鏈接 mysql -h 遠程ip或域名 -p 端口 -u 用戶名 -p 密碼
mysql -u root -p
複製代碼
雖然密碼也能夠直接跟在 -p 後面寫在命令行中,但可能會致使你的密碼泄露。
將客戶端鏈接到服務端
獲取到權限等信息
從權限表裏邊查詢用戶權限並保存在一個變量裏邊以供查詢緩存。
分析器,執行器在檢查權限的時候使用。
在鏈接的有效時長內對sql進行處理。
interactive_timeout
wait_timeout
複製代碼
其中 wait_timeout是非交互式鏈接的空閒超時,interactive_timeout是交互式鏈接的空閒超時。
在鏈接時最好使用長連接,可是MySQL 在執行過程當中臨時使用的內存在鏈接的對象裏,而且這些資源會在鏈接斷開的時候才釋放。 因此會佔用不少內存,達到必定值後有可能被系統強制殺死。
有兩個方法:
按期斷開長鏈接。
使用一段時間,或者執行過一個佔用內存的查詢操做後,斷開鏈接。
可使用這個API來從新初始化鏈接資源,將鏈接恢復到剛剛建立完時的狀態。
mysql_reset_connection
複製代碼
拿到語句,先到緩存以(key-value的形式查詢),若是內存中有,則把value返回。你們可能以爲緩存這個東西不錯嗷,能夠減小mysql的工做量。若是以前查詢過直接把值拿過來就能夠了。可是水水卻以爲緩存儘可能別用~你們先別急,往下看。
查詢緩存的失效很是頻繁,只要有一個表的更新,那麼這個表上全部的查詢緩存都會被清空。這就會引起一個很大的問題,對於更新頻繁的數據庫來講,查詢緩存的命中率會很是低。並且查詢緩存是要從內存中去查詢,命中率低會影響數據庫服務器的性能。所以水水建議若是數據庫表常常更新,最好不要使用緩存。
mysql> show variables like '%query_cache%';
複製代碼
mysql> select SQL_NO_CACHE count(host) from user;
複製代碼
分析器主要負責將命令拆分紅詞來進行詞法和語法分析。
詞法分析:識別關鍵字,表名,列名等等(查看錶,列是否存在)從information schema裏面得到表的信息的。
語法分析:是否知足sql語法
答案是經過解析器和預處理器~
mysql經過 關鍵詞 將sql命令語句解析成一棵 「解析樹」
解析器處理語法和解析查詢,主要有驗證關鍵詞的拼寫和順序是否正確。
若是語法不正確會出現 "You have an error in your SQL syntax"
預處理器進一步檢查解析樹是否合法。主要有 檢查表和列是否存在,別名是否被佔用等等。
預處理器驗證用戶是否有查詢權限。
若是經過則生成新的解析樹,再提交給優化器。
決定使用哪一個索引(表中有多個索引) 或者在一個語句有多表關聯(join)的時候,決定各個表的鏈接順序。最後生成執行計劃進入執行器。
res= select_precheck(thd, lex, all_tables, first_table);
複製代碼
根據指令,經過API調用底層存儲引擎執行。
mysql實現了一個抽象接口層 handler(sql/handler.h)
若是使用觸發器,得在執行器階段才能肯定。 因此分析器工做結束後的precheck是不能對這種運行時涉及到的表進行權限校驗的,因此須要在執行器階段進行權限檢查。 另外正是由於有precheck這個步驟,纔會在報錯時報的是用戶無權限,而不是 k字段不存在,以避免暴露表結構。