1. 程式人生 > >explain sql 結果引數解讀

explain sql 結果引數解讀

● explain結果:

mysql> explain select * from emp;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
|  1 | SIMPLE      | emp   | NULL       | ALL  | NULL          | NULL | NULL    | NULL |   12 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+

● id
id值相同,從上往下 順序執行
表的執行順序 因表的資料量改變而改變的原因: 笛卡兒積,資料小的表 優先查詢
id值不同:id值越大越優先查詢 (本質:在巢狀子查詢時,先查內層 再查外層)
id值有相同,又有不同: id值越大越優先;id值相同,從上往下 順序執行

● select_type : :查詢型別
PRIMARY:包含子查詢sql中 主查詢(最外層)
SUBQUERY:包含子查詢sql中的 子查詢 (非最外層)
simple:簡單查詢(不包含子查詢,union)
derived:衍生查詢(使用到了臨時表)

● type 索引型別
system>const>eq_ref>ref>range>index>all ---對type進行優化的前提:有索引

其中system,const只是理想中的情況,實際一般在ref>range
system(忽略): 只有一條資料的系統表 ;或 衍生表只有一條資料的主查詢

const:僅僅能查到一條資料的SQL ,用於Primary key 或unique索引 (型別 與索引型別有關)
eq_ref:唯一性索引:對於每個索引鍵的查詢,返回匹配唯一行資料(有且只有1個,不能多 、不能0)
ref:非唯一性索引,對於每個索引鍵的查詢,返回匹配的所有行(0,多)
range:檢索指定範圍的行 ,where後面是一個範圍查詢(between ,> < >=, 特殊:in有時候會失效 ,從而轉為 無索引all)

index:查詢全部索引中資料
explain select tid from teacher ; --tid 是索引, 只需要掃描索引表,不需要所有表中的所有資料

all:查詢全部表中的資料
explain select cid from course ;  --cid不是索引,需要全表所有,即需要所有表中的所有資料

system/const: 結果只有一條資料
eq_ref:結果多條;但是每條資料是唯一的 ;
ref:結果多條;但是每條資料是是0或多條 ;

● possible_keys : 可能用到的索引,是一種預測,不準。
``
● key : 實際使用到的索引
● key_len :索引的長度,用來判斷符合索引是否完全被使用(mysql中一個字元佔3個位元組)
● ref : 此ref與type的ref是兩個概念, 指明當前表所參照的欄位
● rows : 被索引優化查詢的資料個數(實際通過索引而查詢到的資料個數)
● Extra:
1. using filesort:效能消耗大;需要“額外”的一次排序(查詢) 。常見於 order by 語句中。

explain select * from test02 where id> 1 order by id ;
小結:對於單索引, 如果排序和查詢是同一個欄位,則不會出現using filesort;如果排序和查詢不是同一個欄位,則會出現using filesort;
避免方法: where哪些欄位,就order by那些欄位

複合索引:不能跨列(最佳左字首)
避免方法: where和order by 按照複合索引的順序使用,不要跨列或無序使用。

2.using temporary:效能損耗大 ,用到了臨時表。一般出現在group by 語句中。

	explain select a1 from test02 where a1 in ('1','2','3') group by a1 ;
	explain select a1 from test02 where a1 in ('1','2','3') group by a2 ; --using temporary
	避免方法:查詢那些列,就根據那些列 group by .

3.using index::效能提升; 索引覆蓋(覆蓋索引)。原因:不讀取原檔案,只從索引檔案中獲取資料 (不需要回表查詢)只要使用到的列 全部都在索引中,就是索引覆蓋using index

例如:test02表中有一個複合索引(a1,a2,a3)
	explain select a1,a2 from test02 where a1='' or a2= '' ; --using index   

	drop index idx_a1_a2_a3 on test02;

	alter table test02 add index idx_a1_a2(a1,a2) ;
	explain select a1,a3 from test02 where a1='' or a3= '' ;


	如果用到了索引覆蓋(using index時),會對 possible_keys和key造成影響:
	a.如果沒有where,則索引只出現在key中;
	b.如果有where,則索引 出現在key和possible_keys中。

	explain select a1,a2 from test02 where a1='' or a2= '' ;
	explain select a1,a2 from test02  ;

4.using where : 需要回表查詢

假設age是索引列
但查詢語句select age,name from ...where age =...,此語句中必須回原表查Name,因此會顯示using where.
explain select a1,a3 from test02 where a3 = '' ; --a3需要回原表查詢

5.impossible where :where子句永遠為false
explain select * from test02 where a1='x' and a1='y' ;

● SQL編寫、解析過程

編寫過程:
select dinstinct  ..from  ..join ..on ..where ..group by ...having ..order by ..limit ..

解析過程:			
from .. on.. join ..where ..group by ....having ...select dinstinct ..order by limit ...