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 ...