執(zhí)行計(jì)劃

image.png
image.png

執(zhí)行計(jì)劃中包含的信息

1.id

select查詢的序列號(hào),包含一組數(shù)字,表示查詢中執(zhí)行select子句或者操作表的順序
id號(hào)分為三種情況:
1、如果id相同,那么執(zhí)行順序從上到下
2、如果id不同,如果是子查詢,id的序號(hào)會(huì)遞增,id值越大優(yōu)先級(jí)越高,越先被執(zhí)行
3、id相同和不同的,同時(shí)存在:相同的可以認(rèn)為是一組,從上往下順序執(zhí)行,在所有組中,id值越大,優(yōu)先級(jí)越高,越先執(zhí)行

2.select_type

主要用來分辨查詢的類型,是普通查詢還是聯(lián)合查詢還是子查詢

--sample:簡單的查詢,不包含子查詢和union 
    explain select * from emp; 
--primary:查詢中若包含任何復(fù)雜的子查詢,最外層查詢則被標(biāo)記為Primary 
    explain select staname,ename supname from (select ename staname,mgr from emp) t join emp on t.mgr=emp.empno ; 
--union:若第二個(gè)select出現(xiàn)在union之后,則被標(biāo)記為union 
    explain select * from emp where deptno = 10 union select * from emp where sal >2000;
 --dependent union:跟union類似,此處的depentent表示union或union all聯(lián)合而成的結(jié)果會(huì)受外部表影響
     explain select * from emp e where e.empno  in ( select empno from emp where deptno = 10 union select empno from emp where sal >2000) 
--union result:從union表獲取結(jié)果的select 
    explain select * from emp where deptno = 10 union select * from emp where sal >2000; 
--subquery:在select或者where列表中包含子查詢 
     explain select * from emp where sal > (select avg(sal) from emp) ; 
--dependent subquery:subquery的子查詢要受到外部表查詢的影響 
    explain select * from emp e where e.deptno in (select distinct deptno from dept); 
--DERIVED: from子句中出現(xiàn)的子查詢,也叫做派生類, 
    explain select staname,ename supname from (select ename staname,mgr from emp) t join emp on t.mgr=emp.empno ; 
--UNCACHEABLE SUBQUERY:表示使用子查詢的結(jié)果不能被緩存 
    explain select * from emp where empno = (select empno from emp where deptno=@@sort_buffer_size); 
--uncacheable union:表示union的查詢結(jié)果不能被緩存:sql語句未驗(yàn)證

3.table

對(duì)應(yīng)行正在訪問哪一個(gè)表,表名或者別名,可能是臨時(shí)表或者union合并結(jié)果集
1、如果是具體的表名,則表明從實(shí)際的物理表中獲取數(shù)據(jù),當(dāng)然也可以是表的別名
2、表名是derivedN的形式,表示使用了id為N的查詢產(chǎn)生的衍生表
3、當(dāng)有union result的時(shí)候,表名是union n1,n2等的形式,n1,n2表示參與union的id

4.type

type顯示的是訪問類型,訪問類型表示我是以何種方式去訪問我們的數(shù)據(jù),最容易想的是全表掃描,直接暴力的遍歷一張表去尋找需要的數(shù)據(jù),效率非常低下,訪問的類型有很多,效率從最好到最壞依次是:

system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL

一般情況下,得保證查詢至少達(dá)到range級(jí)別,最好能達(dá)到ref


--all:全表掃描,一般情況下出現(xiàn)這樣的sql語句而且數(shù)據(jù)量比較大的話那么就需要進(jìn)行優(yōu)化。 
    explain select * from emp; 
--index:全索引掃描這個(gè)比all的效率要好,主要有兩種情況,一種是當(dāng)前的查詢時(shí)覆蓋索引,即我們需要的數(shù)據(jù)在索引中就可以索取,或者是使用了索引進(jìn)行排序,這樣就避免數(shù)據(jù)的重排序 
    explain  select empno from emp;
 --range:表示利用索引查詢的時(shí)候限制了范圍,在指定范圍內(nèi)進(jìn)行查詢,這樣避免了index的全索引掃描,適用的操作符: =, <>, >, >=, <, <=, IS NULL, BETWEEN, LIKE, or IN() 
    explain select * from emp where empno between 7000 and 7500;
 --index_subquery:利用索引來關(guān)聯(lián)子查詢,不再掃描全表
     explain select * from emp where emp.job in (select job from t_job); 
--unique_subquery:該連接類型類似與index_subquery,使用的是唯一索引 
      explain select * from emp e where e.deptno in (select distinct deptno from dept); 
--index_merge:在查詢過程中需要多個(gè)索引組合使用,沒有模擬出來
     explain select * from rental where rental_date like '2005-05-26 07:12:2%' and inventory_id=3926 and customer_id=321\G 
--ref_or_null:對(duì)于某個(gè)字段即需要關(guān)聯(lián)條件,也需要null值的情況下,查詢優(yōu)化器會(huì)選擇這種訪問方式
     explain select * from emp e where e.mgr is null or e.mgr=7369; 
--ref:使用了非唯一性索引進(jìn)行數(shù)據(jù)的查找 create index idx_3 on emp(deptno);  
     explain select * from emp e,dept d where e.deptno =d.deptno; 
--eq_ref :使用唯一性索引進(jìn)行數(shù)據(jù)查找
     explain select * from emp,emp2 where emp.empno = emp2.empno; 
--const:這個(gè)表至多有一個(gè)匹配行,
     explain select * from emp where empno = 7369;
 --system:表只有一行記錄(等于系統(tǒng)表),這是const類型的特例,平時(shí)不會(huì)出現(xiàn)

5.possible_keys

顯示可能應(yīng)用在這張表中的索引,一個(gè)或多個(gè),查詢涉及到的字段上若存在索引,則該索引將被列出,但不一定被查詢實(shí)際使用

explain select * from emp,dept where emp.deptno = dept.deptno and emp.deptno = 10;

6.key

實(shí)際使用的索引,如果為null,則沒有使用索引,查詢中若使用了覆蓋索引,則該索引和查詢的select字段重疊。

explain select * from emp,dept where emp.deptno = dept.deptno and emp.deptno = 10;

7.key_len

表示索引中使用的字節(jié)數(shù),可以通過key_len計(jì)算查詢中使用的索引長度,在不損失精度的情況下長度越短越好。

explain select * from emp,dept where emp.deptno = dept.deptno and emp.deptno = 10;

8.ref

顯示索引的哪一列被使用了,如果可能的話,是一個(gè)常數(shù)

explain select * from emp,dept where emp.deptno = dept.deptno and emp.deptno = 10;

9.rows

根據(jù)表的統(tǒng)計(jì)信息及索引使用情況,大致估算出找出所需記錄需要讀取的行數(shù),此參數(shù)很重要,直接反應(yīng)的sql找了多少數(shù)據(jù),在完成目的的情況下越少越好

explain select * from emp;</pre>

10.extra

包含額外的信息。

--using filesort:說明mysql無法利用索引進(jìn)行排序,只能利用排序算法進(jìn)行排序,會(huì)消耗額外的位置
explain select * from emp order by sal;

--using temporary:建立臨時(shí)表來保存中間結(jié)果,查詢完成之后把臨時(shí)表刪除
explain select ename,count(*) from emp where deptno = 10 group by ename;

--using index:這個(gè)表示當(dāng)前的查詢時(shí)覆蓋索引的,直接從索引中讀取數(shù)據(jù),而不用訪問數(shù)據(jù)表。如果同時(shí)出現(xiàn)using where 表名索引被用來執(zhí)行索引鍵值的查找,如果沒有,表面索引被用來讀取數(shù)據(jù),而不是真的查找
explain select deptno,count(*) from emp group by deptno limit 10;

--using where:使用where進(jìn)行條件過濾
explain select * from t_user where id = 1;

--using join buffer:使用連接緩存,情況沒有模擬出來

--impossible where:where語句的結(jié)果總是false
explain select * from emp where empno = 7469;</pre>

作者:冰憶往昔
鏈接:https://ac.nowcoder.com/discuss/1027408?type=1&order=3&page=1&channel=-1
來源:牛客網(wǎng)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容