explain 的使用和解析
一.作用
使用explain這個命令去查看一個這些SQL語句,查看查詢中表的讀取順序,查詢類型,可以使用的索引,正在使用的索引等,可以讓我們直觀去看到這個SQL語句執行的順序,是否可以優化等
二.示例
EXPLAIN select * from vehicle_company t2 where t2.vehicle_company_id =
(select t1.vehicle_company_id from vehicle_info t1 where t1.vin = 'LGXCE6DB0H0103768')
explain select * from vehicle_info t1
left join vehicle_company t2 on(t2.vehicle_company_id = t1.vehicle_company_id)
where t1.vin = 'LGXCE6DB0H0103768'
and t2.contract_code = 'GZH'
三.解析
共計出現了十二個字段:
id: 表的執行順序
select_type: 查詢的類型
table: 讀取的表
partitions: 匹配的分區
type: 表示表的連接類型
possible_keys: 表示查詢時,可能使用的索引
key: 表示實際使用的索引
key_len: 索引字段的長度
ref: 列與索引的比較
rows: 表掃描的行數
filtered: 按表條件過濾的行百分比
Extra: 執行情況的描述
1.id(兩種情況)
a. id 相同,執行順序從上到下
b. id 不同,id的序號會遞增,id 值越大執行優先級越高
2.select_type
a. SIMPLE: 簡單查詢,查詢中不包含子查詢或者union查詢
b. PRIMARY: 查詢中若包含任何複雜的子部分,最外層爲PRIMARY,也就是最後加載就是PRIMARY
c. SUBQUERY: 在select 或者where 列表中包含了子查詢,就會被標記爲SUBQUERY
d. DERIVED: 在from列表中包含的子查詢會被爲DERIVED
e. UNION: 若是第二個select 出現在union 後,則會被標記爲UNION,若UNION包含再from子句的查詢中,外層select 將被標記爲DERIVED
f. UNION RESULT: 從union表獲取結果的select
3.table
顯示掃描那張表的
4.partitions
5.type
表示查詢所使用的的訪問類型,有八種,性能從差到好(從左到右)排列
ALL -> index -> range -> ref -> eq_ref -> const -> system -> NULL
a. ALL: MySQL 將遍歷全表以找到匹配的行
b. index: index與ALL 區別爲index 類型只遍歷索引樹
c. range: 只檢索給定範圍的行,使用一個索引來選擇行
d. ref: 表示上述表的連接匹配條件,即那些列或常量被用於查找索引列上的值
e. eq_ref: 類似ref,區別就在使用的索引是唯一索引,對於每個索引鍵值,表中只有一條記錄匹配,簡單來說,就是多表連接中使用primary key 或者unique key作爲關聯條件
f. const/system:當MySQL對查詢某部分進行優化,並轉換爲一個常量時,使用這些類型訪問。如將主鍵置於where列表中,MySQL就能將該查詢轉換爲一個常量,system是const類型的特例,當查詢的表只有一行的情況下,使用system
g. NULL: MySQL在優化過程中分解語句,執行時甚至不用訪問表或索引,例如從一個索引列裏選取最小值可以通過單獨索引查找完成。
一般來說,需保證查詢至少達到range級別,最好能達到ref
6.possible_keys
被連接的表中的索引,可能一個或多個,查詢涉及到的字段若存在改索引,則該索引被列出,但是不一定被使用
7.key
查詢實際使用的索引,如果爲NULL,則表示未使用索引,若查詢中使用的覆蓋索引,則改索引和查詢的select 字段重疊
8.key_len
索引中所使用的字節數,可通過該列計算查詢中使用的長度(key_len 顯示的值爲索引字段的最大可能長度,並非實際使用長度),
在保證選擇性的情況下,索引長度越短越好-- 前綴索引
9.ref
列與索引的比較,表示上述表的連接匹配條件,即那些列或常量被用於查找索引上的值
10.rows
估算出找到所需記錄所要讀取的行數,該值越小越好
11.filtered
表示存儲引擎返回的數據經過濾後,剩下多少滿足條件記錄數量的比例
12.Extra
a. Using filesort:表示對數據使用一個外部的索引排序,而不是按照表內的索引順序進行讀取,MySQL中無法利用索引完成的排序操作稱爲"文件排序",出現這個儘快優化SQL,數據量大的時候很危險
例如:使用表中非索引字段排序
b. Using temporary:使用了零時表保存中間結果,常見於排序order by 和分組查詢group by ,出現這種情況也要優化索引
c. Using index:表名相應的select 操作中使用覆蓋索引,避免訪問了表的數據行,如果同時出現using where,表名索引被用來執行索引鍵值的查找;如果沒有同時出現using where,表名索引用來讀取數據而非執行查詢動作。
d. Using where: 表名使用where 過濾
e. impossible where:where子句的值總是false,不能用來獲取任何元組
f. select tables optimized away:在沒有group by子句的情況下,基於索引優化Min、max操作或者對於MyISAM存儲引擎優化count(*),不必等到執行階段再進行計算,查詢執行計劃生成的階段即完成優化。
g. distinct:優化distinct操作,在找到第一匹配的元組後即停止找同樣值的動作。