SQL做爲Web開發是永遠離開不的一個話題,每天寫SQL,但是你知道一個SQL是如何執行的嗎?mysql
select name from user where id = 1;
上面是一個簡單的查詢語句,交給數據庫去執行,而後返回name。看起來很簡單,但是內部的執行過程卻不少人都不知道。面試
今天就把MySQL拆開看看,看一下它到底是怎麼工做的。算法
從上圖能夠看出,MySQL分爲Server
層和存儲引擎層
sql
鏈接器主要是與客戶端創建鏈接, 包含本地socket和大多數基於客戶端/服務端工具實現的相似於tcp/ip的通訊。 鏈接成功以後會同時校驗用戶的權限,等相關安全方案。如咱們經常使用的創建鏈接方式數據庫
mysql -h ip -P 3306 -u root -p
鏈接是能夠在-p後面輸入密碼,可是考慮到安全問題 不建議這樣操做,-P 後是端口號,-p 是密碼。注意大小寫。
登陸成功以後,會校驗固然登陸帳號的權限。後續全部的數據庫操做都被當前權限所限制。所以,管理員修改用戶權限時,不會當即生效,須要從新鏈接纔會生效。windows
MySQL默認狀況下,當一個連接空閒超過8(60 60 8)小時以後會自動斷開鏈接。可是鏈接池則覺得該被斷開的鏈接依然有效。 這個時候若是客戶端代碼發送請求時,鏈接池會把已經失效的代碼返回至客戶端。這樣就會致使代碼異常。緩存
經過show global variables like '%timeout%'
可進行查看, 缺省狀況下是使用wait_timeout 這個字段。安全
另外能夠用show processlist;
用來顯示用戶正在運行的線程。架構
注意:除了 root 用戶能看到全部正在運行的線程外,其餘用戶都只能看到本身正在運行的線程,看不到其它用戶正在運行的線程。除非單獨個這個用戶賦予了PROCESS 權限。
mysql> show processlist; +----+-----------------+-----------+------+---------+------+------------------------+------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+-----------------+-----------+------+---------+------+------------------------+------------------+ | 4 | event_scheduler | localhost | NULL | Daemon | 461 | Waiting on empty queue | NULL | | 13 | root | localhost | NULL | Query | 0 | starting | show processlist | +----+-----------------+-----------+------+---------+------+------------------------+------------------+
當咱們創建鏈接以後,執行SQL語句時,會先進行緩存查詢(若是開啓了緩存查詢)。若是以前執行了相同的SQL語句,則會從緩存中直接返回結果。 這個過程能夠理解爲SQL文本和查詢結果的映射。併發
可是查詢緩存真的能提高效率嗎? 理論上,不建議開啓查詢緩存
由於緩存和失效都會有額外的資源消耗,數據發生改變或者表結構發生改變時,都會致使緩存失效。最差的狀況就是你剛創建了一份緩存,另一邊又有人修改數據。這樣致使緩存失效,從新創建了一份新的緩存。
有這些INSERT、UPDATE、 DELETE、TRUNCATE、ALTER TABLE、DROP TABLE或DROP DATABASE會致使緩存數據失效。因此查詢緩存適合有大量相同查詢的應用,不適合有大量數據更新的應用
在MySQL8.0的版本刪除了查詢緩存的功能。
若是你是8.0以前的版本,能夠經過如下方法關閉查詢緩存:
一、臨時關閉,直接執行命令行
set global query_cache_size=0 set global query_cache_type=0
二、永久關閉,修改配置文件my.cnf ,添加下面的配置便可。
query_cache_type=0 query_cache_size=0
當在查詢緩存中沒有找到對象的查詢結果時,這時候就須要分析器對SQL進行解析。好比解析出響應的關鍵詞。如Select(查詢)、Delete(刪除)等等,同時也會把相應的代表、字段名都分析出來。若是SQL語法錯誤,會告訴咱們 You have an error in your SQL syntax
SQL實際的執行順序不必定就是咱們寫的順序。在經過分析器的解析,數據庫知道了咱們要作什麼。而後會按照必定的規則重寫SQL。當有多個索引的時候,優化器也會決定去使用哪一個索引;當多表關聯查詢的時候,也會去決定各個表的連接順序。總之,優化器會經過一系列的算法規則去給出一個最優的執行策略。
SQL經過分析器知道要作什麼,經過優化器知道該怎麼作。最後經過執行器就進入了執行階段。
首先會根據鏈接的帳號查看是否有操做該表的權限。若是沒有,則返回權限錯誤。若是有權限,則繼續執行。
打開表的時候,執行器會根據表的引擎 去使用該引擎提供的接口。
存儲引擎層負責數據的存儲和提取。
可經過show engines
查看MySQL的存儲引擎。存儲引擎有 InnoDB
、 MylSAM
、 MEMORY
、 MERGE
等等..
可是咱們經常使用的基本是InnoDB
和MylSAM
。
InnoDB在5.5.5版本以後爲默認的存儲引擎
InnoDB是一個事務型的存儲引擎,有行級鎖定和外鍵約束,提供了具備提交,回滾和崩潰恢復的事務安全,可是對比MyLSAM引擎,寫的效率會比差一些,而且會佔用更多的磁盤空間以保持數據和索引。
特色:
Mylsam 存儲引擎獨立於操做系統,簡單說就是可用在windows上使用,也可用將數據轉移到Lunex操做系統上。系統兼容性很好!!!。這種存儲引擎在建表的時候,它會建立3個文件。分別是(.frm, .MYD, .MYI),簡單說明一下:.frm 存儲表的定義(也就是表結構啦),.MYD 就是表裏面的數據,.MYD存儲索引。這樣的劃分操做系統對大文件的操做是比較慢的,這樣將表分爲三個文件,那麼.MYD這個文件單獨來存放數據天然能夠優化數據庫的查詢等操做。
特色:
一、不支持事務
二、不支持外鍵
三、查詢速度很快。若是數據庫insert和update的操做比較多的話採用表鎖效率低(建議使用innodb)。
四、對錶進行加鎖
Server層涵蓋了MySQL執行的大多數的核心功能,以及各類各樣的內置函數,好比時間、日期等,無論使用的是什麼存儲引擎,它的Server層是同樣的。以上就是對一個SQL執行流程的簡單介紹。感謝你們的閱讀!