一條sql內部是如何執行的:
學習MySQL實戰45專欄
sql中的內部執行圖:
可以分為兩部分:server和儲存引擎
server層包含:
聯結器、分析器、優化器、執行器,涵蓋了MySQL大多數核心服務功能,以及所有的內建函式(如日期、時間、數學和加密函式等),相關功能:儲存過程、觸發器、檢視都在這一層實現。
儲存引擎層:
負責資料的儲存和提取,儲存引擎是可以多選的,支援 InnoDB MyISAM、
Memory 等,現在最常用的儲存引擎是 InnoDB,它從 MySQL 5.5.5 版本開始成為了預設儲存引擎
指定儲存引擎:engine=memory
不同儲存引擎的表資料存取方式不同,支援的功能也不同.
select * from T where ID=10;
聯結器:
查詢快取:
連線建立後,就可以執行select語句,然後會進行查詢快取,
MySQL收到查詢請求後,會到查詢快取中檢視,其中都是儲存著以key-value形式的鍵值對,key為查詢語句,value為查詢結果,如果有快取則直接返回value。
不在查詢快取中,會執行後續過程,執行完成後會講查詢的結果儲存到快取中;但是查詢快取的弊大於利;
查詢快取的失效非常頻繁,只要有對一個表的更新,這個表上所有的查詢快取都會被清空
按需設定:
- 將引數 query_cache_type 設定成 DEMAND;所有的SQL都不會進行查詢快取
- 通過關鍵字SQL_CACHE 也可以顯示指定
mysql> select SQL_CACHE * from T where ID=10;
在MySQL8.0後取消了這個查詢快取的功能;
分析器:
然後對於sql語句進行分析,主要詞法分析和語法分析
- 把相關的關鍵字、表名、欄位等分析出來
- 根據詞法分析的結果進行語法規則的判斷,不會就會有錯誤提示
You have an error in your SQL syntax
,然後看use near
後面的資訊;
優化器:
通過分析器,MySQL知道了執行目的;主要是決定sql中執行的順序,
優化器是在表裡面有多個索引的時候,決定使用哪個索引;或者在一個語句有多表關聯(join)的時候,決定各個表的連線順序
select * from t1 join t2 using(ID) where t1.c=10 and t2.d=20;
--等價於
select * from ti join t2 where t1.ID = t2.ID and ti.c = 10 and t2.d = 20;
不同的執行順序,所執行的效率是不一樣的;
- 既可以先從表 t1 裡面取出 c=10 的記錄的 ID 值,再根據 ID 值關聯到表 t2,再判斷 t2 裡面 d 的值是否等於 20。
- 也可以先從表 t2 裡面取出 d=20 的記錄的 ID 值,再根據 ID 值關聯到 t1,再判斷 t1 裡面 c 的值是否等於 10。
執行器:
MySQL 通過分析器知道了你要做什麼,通過優化器知道了該怎麼做,於是就進入了執行器階段,開始執行語句;
在工程實現上,如果命中查詢快取(mysql8已取消),會在查詢快取返回結果的時候,做許可權驗證。查詢也會在優化器之前呼叫 precheck 驗證許可權