mysql explain用法和結果分析

explain簡介:
使用explain關鍵字可以模擬優化器執行sql查詢語句,從而知道mysql是如何處理你的sql語句。
使用方式如下:explain sql。
執行計劃包含的信息:

+----+-------------+----------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table    | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra |
+----+-------------+----------+------------+------+---------------+------+---------+------+------+----------+-------+

執行計劃各字段含義:
1:id:select查詢的序列號,包含一組數字,表示查詢中執行select子句或操作表的順序。
id的結果共有三種情況:
1.1:id相同,執行順序由上而下。
在這裏插入圖片描述
上圖中的table列表示加載表的順序:t1、t2、t3。

1.2:id不同,如果是子查詢,id的序號會遞增,id值越大優先級越高,越先被執行。
在這裏插入圖片描述
1.3:id相同、不同同時存在。
在這裏插入圖片描述
如上圖所示,在id爲1時,table顯示的是 ,這裏指的是指向id爲2的表,即t3表的衍生表。

2:select_type:用來表示查詢的類型,主要是用於區別普通查詢、聯合查詢、子查詢等的複雜查詢。
常見和常用的值有以下幾種:
在這裏插入圖片描述
simple:簡單的select查詢,查詢中不包含子查詢或者union。

explain select * from sdb_b2c_orders left join sdb_b2c_order_items on sdb_b2c_orders.order_id=sdb_b2c_order_items.order_id where sdb_b2c_orders.order_id=20191018149974

在這裏插入圖片描述
primary:查詢中若包含任何複雜的子查詢,最外層查詢會被標記爲primary。
subquery:在select或where列表中包含了子查詢。

explain select * from sdb_b2c_orders where member_id = (select member_id from sdb_b2c_members where mobile=18202139749)

在這裏插入圖片描述
DERIVED:在FROM列表中包含的子查詢被標記爲DERIVED(衍生),MySQL會遞歸執行這些子查詢,把結果放在臨時表中。
UNION:若第二個SELECT出現在UNION之後,則被標記爲UNION:若UNION包含在FROM子句的子查詢中,外層SELECT將被標記爲:DERIVED。
UNION RESULT:從UNION表獲取結果的SELECT。

3:table:指的是當前執行的表。

4:type:對錶的訪問方式,表示mysql在表中找到所需行的方式,又稱訪問類型。
常用的類型有: ALL、index、range、 ref、eq_ref、const、system、NULL(從左到右,性能從差到好)
All:mysql將遍歷全表以找到匹配的行。
index:index與All的區別爲index類型只遍歷索引樹。這通常比ALL快,因爲索引文件通常比數據文件小,而且索引數據一般情況下會保存在內存裏。
range:只檢索給定範圍的行,使用一個索引來選擇行,key列顯示使用了哪個索引,一般就是在你的where語句中出現between、<、>、in等的查詢,這種範圍掃描索引要比全索引掃描性能要好,因爲它只需要開始與索引的某一點,而結束與另一點,不用掃描全部索引。
在這裏插入圖片描述
index_merge:在查詢過程中需要多個索引組合使用,通常出現在有or關鍵字的sql語句中。

explain select member_id from sdb_b2c_members where mobile = '18202139749' or name = '姆巴佩';

在這裏插入圖片描述

ref:非唯一性索引掃描,返回匹配某個單獨值的所有行,本質上也是一種索引訪問,它返回所有匹配某個單獨值的行,然而,它可能會找到多個符合條件的行,所以他應該屬於查找和掃描的混合體。

select * from student3;
+----+------+-----+--------+--------+
| id | name | age | height | weight |
+----+------+-----+--------+--------+
|  1 | lbj  |  20 |    203 |    220 |
|  2 | lbj  |  20 |    203 |    220 |
|  3 | lbj  |  20 |    203 |    220 |
+----+------+-----+--------+--------+
3 rows in set (0.00 sec)

mysql>
mysql> explain select * from student3 where name='lbj';
+----+-------------+----------+------------+------+---------------+---------+---------+-------+------+----------+-------------+
| id | select_type | table    | partitions | type | possible_keys | key     | key_len | ref   | rows | filtered | Extra       |
+----+-------------+----------+------------+------+---------------+---------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | student3 | NULL       | ref  | n_a_h_w       | n_a_h_w | 32      | const |    3 |   100.00 | Using index |
+----+-------------+----------+------------+------+---------------+---------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

eq_ref:唯一性索引掃描,對於每個索引鍵,表中只有一條記錄與之匹配,常見於主鍵索引或唯一索引。

const:表示通過索引一次就找到了,const用於比較primary key 或者unique索引。因爲只匹配一行數據,所以很快。如將主鍵置於where列表中,MySQL就能將該查詢轉換爲一個常量。
在這裏插入圖片描述
首先進行子查詢得到一個結果的d1臨時表,子查詢條件爲id = 1 是常量,所以type是const,id爲1的相當於只查詢一條記錄,所以type爲system。

system 表只有一行記錄(等於系統表),這是const類型的特列,平時不會出現,這個也可以忽略不計

5:possible_keys:顯示可能應用在這張表中的索引,一個或多個,查詢涉及到的字段上若存在索引,則該索引將被列出,但不一定被查詢實際使用。

6:key:實際使用的索引,如果爲null,則沒有使用到索引。(可能原因包括沒有建立索引,或索引失效)。
在這裏插入圖片描述
查詢中若使用了覆蓋索引(select後要查詢的字段剛好和創建的索引字段完全相同),則該索引僅出現在key列表中。

explain select name from student3;   name字段建了索引。
+----+-------------+----------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| id | select_type | table    | partitions | type  | possible_keys | key     | key_len | ref  | rows | filtered | Extra       |
+----+-------------+----------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | student3 | NULL       | index | NULL          | n_a_h_w | 44      | NULL |    4 |   100.00 | Using index |
+----+-------------+----------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

7:key_len:表示索引中使用的字節數,可通過該列計算查詢中使用的索引的長度,在不損失精確性的情況下,長度越短越好。key_len顯示的值爲索引字段的最大可能長度,並非實際使用長度,即key_len是根據表定義計算而得,不是通過表內檢索出的。
key_len詳細介紹

8:ref:顯示索引的哪一列被使用了,如果可能的話,是一個常數。哪些列或常量被用於查找索引列上的值

9:rows:根據表統計信息及索引選用情況,大致估算出找到所需的記錄所需要讀取的行數,也就是說,用的越少越好

10:extra:該列包含mysql解決查詢的詳細信息,有以下幾種情況。
Using where:不用讀取表中所有信息,僅通過索引就可以獲取所需數據,這發生在對錶的全部的請求列都是同一個索引的部分的時候,表示mysql服務器將在存儲引擎檢索行後再進行過濾
Using temporary(十死無生):使用了用臨時表保存中間結果,MySQL在對查詢結果排序時使用臨時表。常見於排序order by和分組查詢group by。
在這裏插入圖片描述
Using filesort(九死一生):當Query中包含 order by 操作,而且無法利用索引完成的排序操作稱爲“文件排序”。說明mysql會對數據使用一個外部的索引排序,而不是按照表內的索引順序進行讀取。MySQL中無法利用索引完成的排序操作稱爲“文件排序”。
在這裏插入圖片描述
Using index(發財了):表示相應的select操作中使用了覆蓋索引(Covering Index),避免訪問了表的數據行,效率不錯。如果同時出現using where,表明索引被用來執行索引鍵值的查找;如果沒有同時出現using where,表明索引用來讀取數據而非執行查找動作。
在這裏插入圖片描述
在這裏插入圖片描述
Using join buffer:
表明使用了連接緩存,比如說在查詢的時候,多表join的次數非常多,那麼將配置文件中的緩衝區的join buffer調大一些。

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