前言
在實際資料庫專案開發中,由於我們不知道實際查詢時資料庫裡發生了什麼,也不知道資料庫是如何掃瞄表、如何使用索引的,因此,我們能感知到的就只有sql語句的執行時間。尤其在資料規模比較大的場景下,如何寫查詢、優化查詢、如何使用索引就顯得很重要了。
那麼,問題來了,在查詢前有沒有可能估計下查詢要掃瞄多少行、使用哪些索引呢?
答案是肯定的。以mysql為例,mysql通過explain命令輸出執行計畫,對要執行的查詢進行分析。
什麼是執行計畫呢?
簡單來說,就是sql在資料庫中執行時的表現情況,通常用於sql效能分析、優化等場景。
本文從mysql的邏輯結構講解,過渡到mysql的查詢過程,然後給出執行計畫的例子並重點介紹執行計畫的輸出引數,從而理解為什麼我們會選擇文中建議的方案。
mysql邏輯架構
mysql邏輯架構分為三層,如下圖。
客戶端如,連線處理、授權認證、安全等功能
核心服務
mysql大多數核心服務均在這一層
包括查詢解析、分析、優化、快取、內建函式(如,時間、數學、加密等)
所有的跨儲存引擎的功能也在這一層,如,儲存過程、觸發器、檢視等
儲存引擎
負責mysql中的資料儲存和讀取
中間的服務層通過api與儲存引擎通訊,這些api遮蔽了不同儲存引擎間的差異
重點解釋下查詢快取:對於select語句,在解析查詢之前,伺服器會先檢查查詢快取(query cache)。如果命中,伺服器便不再執行查詢解析、優化和執行的過程,而是直接返回快取中的結果集。
mysql查詢過程
如果能搞清楚mysql是如何優化和執行查詢的,對優化查詢一定會有幫助。很多查詢優化實際上就是遵循一些原則讓優化器能夠按期望的合理的方式執行。
下圖是mysql執行乙個查詢的過程。實際上每一步都比想象中的複雜,尤其優化器,更複雜也更難理解。本文只給予簡單的介紹。
mysql查詢過程如下:
客戶端將查詢傳送到mysql伺服器
伺服器先檢查查詢快取,如果命中,立即返回快取中的結果;否則進入下一階段
伺服器對sql進行解析、預處理,再由優化器生成物件的執行計畫
mysql根據優化器生成的執行計畫,呼叫儲存引擎api來執行查詢
伺服器將結果返回給客戶端,同時快取查詢結果
執行計畫
優化與執行
mysql會解析查詢,並建立內部資料結構(解析樹),並對其進行各種優化,包括重寫查詢、決定表的讀取順序、選擇合適的索引等。
使用者可通過關鍵字提示(hint)優化器,從而影響優化器的決策過程。也可以通過通過優化器解釋(explain)優化過程的各個因素,使使用者知道資料庫是如何進行優化決策的,並提供乙個參考基準,便於使用者重構查詢和資料庫表的schema、修改資料庫配置等,使查詢盡可能高效。
例子看個例子。
mysql> explain select name, nickname, ctime from dt_user where city = 'shanghai' order by name;
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | extra |
| 1 | ****** | dt_user | range | primary,idx_city_name | idx_city_name | 2945 | null | 55183 | using index condition |
1 row in set (0.00 sec)
這個執行計畫給出的資訊是,該查詢通過乙個簡單的給定範圍的掃瞄,共掃瞄55183行,使用index condition條件在dt_user表中篩選出,掃瞄過程中使用primary和idx_city_name索引。
輸出引數
idselect查詢序列號
id相同,執行順序由上至下;id不同,id值越大優先順序越高,越先被執行
select_type
查詢資料的操作型別,有如下
table
顯示該行資料是關於哪張表
partitions
匹配的分割槽
type
表的連線型別,其值、效能由高到底排列如下
前5種情況都是理想的索引的情況。通常優化至少到range級別,最好能優化到ref。
possible_keys
指出 mysql 使用哪個索引在該錶找到行記錄。如果該值為 null,說明沒有使用索引,可以建立索引提高效能
key顯示 mysql 實際使用的索引。如果為 null,則沒有使用索引查詢
key_len
表示索引中使用的位元組數,通過該列計算查詢中使用的索引的長度。在不損失精確性的情況下,長度越短越好顯示的是索引欄位的最大長度,並非實際使用長度
ref顯示該錶的索引字段關聯了哪張表的哪個字段
rows
根據表統計資訊及選用情況,大致估算出找到所需的記錄或所需讀取的行數,數值越小越好
filtered
返回結果的行數佔讀取行數的百分比,值越大越好
extra
包含不適合在其他列中顯示但十分重要的額外資訊。常見的值如下
小結資料庫效能優化很多,本文只簡單了介紹mysql邏輯結構、查詢過程和執行計畫引數。根據執行計畫輸出的索引使用情況、掃瞄的行數可以預估查詢效率,幫助我們重構查詢、優化表結構或者索引,從而盡可能提供查詢效率。
reference
MYSQL執行計畫字段詳解
mysql檢視執行計畫 explain sql 輸出執行計畫。explain extended sql 會在 explain 的基礎上額外提供一些查詢優化的資訊。緊隨其後通過 show warnings 命令可以 得到優化後的查詢語句,從而看出優化器優化了什麼。額外還有 filtered 列,是乙個...
Mysql執行計畫 Extra列解析
mysql的執行計畫中,其他的列都比較好理解,唯獨這個extra列,總是看得有點讓人似懂非懂,先終於找了個機會自己研究了下。using index 中文名叫做索引覆蓋查詢 如果查詢的時候,用到了索引,並且你最終需要的資料也是這個索引的一部分,那麼就出現using index.例如 user表有索引 ...
mysql執行計畫 MySQL 執行計畫
1.執行計畫的定義 什麼是執行計畫 查詢計畫 呢?執行計畫就是一系列的操作步驟。sql是宣告性語言,它只告訴資料庫要查詢什麼,但並不告訴資料庫如何去查。資料庫所要做的就是基於演算法和統計資訊計算出一條最佳的訪問路徑。這個工作是由優化器來完成的。優化器會比較不同的執行計畫,然後選擇其中最優的一套。2....