mysql優化器


在這裏插入圖片描述
1.當客戶端連接到MySQL服務器時,服務器對其進行認證。可以通過用戶名與密碼認證,也可以通過SSL證書進行認證。登錄認證後,服務器還會驗證客戶端是否有執行某個查詢的操作權限。

2.在正式查詢之前,服務器會檢查查詢緩存,如果能找到對應的查詢,則不必進行查詢解析,優化,執行等過程,直接返回緩存中的結果集。

3.MySQL的解析器會根據查詢語句,構造出一個解析樹,主要用於根據語法規則來驗證語句是否正確,比如SQL的關鍵字是否正確,關鍵字的順序是否正確。

而預處理器主要是進一步校驗,比如表名,字段名是否正確等

4.查詢優化器將解析樹轉化爲查詢計劃,一般情況下,一條查詢可以有很多種執行方式,最終返回相同的結果,優化器就是根據成本找到這其中最優的執行計劃

5.執行計劃調用查詢執行引擎,而查詢引擎通過一系列API接口查詢到數據

6.得到數據之後,在返回給客戶端的同時,會將數據存在查詢緩存中

在開篇的圖裏面,我們知道了SQL語句從客戶端經由網絡協議到查詢緩存,如果沒有命中緩存,再經過解析工作,得到準確的SQL,現在就來到了我們這模塊說的優化器。

首先,我們知道每一條SQL都有不同的執行方法,要不通過索引,要不通過全表掃描的方式。

那麼問題就來了,MySQL是如何選擇時間最短,佔用內存最小的執行方法呢?

什麼是成本?

1.I/O成本。數據存儲在硬盤上,我們想要進行某個操作需要將其加載到內存中,這個過程的時間被稱爲I/O成本。默認是1。

2.CPU成本。在內存對結果集進行排序的時間被稱爲CPU成本。默認是0.2。

單表查詢的成本

先來建一個用戶表dev_user,裏面包括主鍵id,用戶名username,密碼password,外鍵user_info_id,狀態status,外鍵main_station_id,是否外網訪問visit,這七個字段。索引有兩個,一個是主鍵的聚簇索引,另一個是顯式添加的以username爲字段的唯一索引uname_unique。
在這裏插入圖片描述
如果搜索條件是select * from dev_user where username=‘XXX’,那麼MySQL是如何選擇相關索引呢?
1.使用所有可能用到的索引
我們可以看到搜索條件username,所以可能走uname_unique索引。也可以做聚簇索引,也就是全表掃描。
2.計算全表掃描代價
我們通過show table status like ‘dev_user’命令知道rows和data_length字段,如下圖。
在這裏插入圖片描述
ows:表示表中的記錄條數,但是這個數據不準確,是個估計值。

data_length:表示表佔用的存儲空間字節數。

data_length=聚簇索引的頁面數量X每個頁面的大小

反推出頁面數量=1589248÷16÷1024=97

I/O成本:97X1=97

CPU成本:6141X0.2=1228

總成本:97+1228=1325

3.計算使用不同索引執行查詢的代價

因爲要查詢出滿足條件的所有字段信息,所以要考慮回表成本。

I/O成本=1+1X1=2(範圍區間的數量+預計二級記錄索引條數)

CPU成本=1X0.2+1X0.2=0.4(讀取二級索引的成本+回表聚簇索引的成本)

總成本=I/O成本+CPU成本=2.4

4.對比各種執行方案的代價,找出成本最低的那個

多表查詢的成本

對於兩表連接查詢來說,他的查詢成本由下面兩個部分構成:

  • 單次查詢驅動表的成本
  • 多次查詢被驅動表的成本(具體查詢多次取決於對驅動表查詢的結果集有多少個記錄)

index dive

如果前面的搜索條件不是等值,而是區間,如select * from dev_user where username>‘admin’ and username<'test’這個時候我們是無法看出需要回表的數量。

步驟1:先根據username>'admin’這個條件找到第一條記錄,稱爲區間最左記錄。

步驟2:再根據username<'test’這個條件找到最後一條記錄,稱爲區間最右記錄。

步驟3:如果區間最左記錄和區間最右記錄相差不是很遠,可以準確統計出需要回表的數量。如果相差很遠,就先計算10頁有多少條記錄,再乘以頁面數量,最終模糊統計出來。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章