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

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

? 在企業(yè)的應(yīng)用場(chǎng)景中,為了知道優(yōu)化SQL語(yǔ)句的執(zhí)行,需要查看SQL語(yǔ)句的具體執(zhí)行過(guò)程,以加快SQL語(yǔ)句的執(zhí)行效率。

? 可以使用explain+SQL語(yǔ)句來(lái)模擬優(yōu)化器執(zhí)行SQL查詢語(yǔ)句,從而知道m(xù)ysql是如何處理sql語(yǔ)句的。

? 官網(wǎng)地址: https://dev.mysql.com/doc/refman/5.5/en/explain-output.html

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

Column Meaning
id The SELECT identifier
select_type The SELECT type
table The table for the output row
partitions The matching partitions
type The join type
possible_keys The possible indexes to choose
key The index actually chosen
key_len The length of the chosen key
ref The columns compared to the index
rows Estimate of rows to be examined
filtered Percentage of rows filtered by table condition
extra Additional information

id

select查詢的序列號(hào),包含一組數(shù)字,表示查詢中執(zhí)行select子句或者操作表的順序

id號(hào)分為三種情況:

? 1、如果id相同,那么執(zhí)行順序從上到下

explain select * from emp e join dept d on e.deptno = d.deptno join salgrade sg on e.sal between sg.losal and sg.hisal;

? 2、如果id不同,如果是子查詢,id的序號(hào)會(huì)遞增,id值越大優(yōu)先級(jí)越高,越先被執(zhí)行

explain select * from emp e where e.deptno in (select d.deptno from dept d where d.dname = 'SALES');

? 3、id相同和不同的,同時(shí)存在:相同的可以認(rèn)為是一組,從上往下順序執(zhí)行,在所有組中,id值越大,優(yōu)先級(jí)越高,越先執(zhí)行

explain select * from emp e join dept d on e.deptno = d.deptno join salgrade sg on e.sal between sg.losal and sg.hisal where e.deptno in (select d.deptno from dept d where d.dname = 'SALES');

select_type

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

select_type Value Meaning
SIMPLE Simple SELECT (not using UNION or subqueries)
PRIMARY Outermost SELECT
UNION Second or later SELECT statement in a UNION
DEPENDENT UNION Second or later SELECT statement in a UNION, dependent on outer query
UNION RESULT Result of a UNION.
SUBQUERY First SELECT in subquery
DEPENDENT SUBQUERY First SELECT in subquery, dependent on outer query
DERIVED Derived table
UNCACHEABLE SUBQUERY A subquery for which the result cannot be cached and must be re-evaluated for each row of the outer query
UNCACHEABLE UNION The second or later select in a UNION that belongs to an uncacheable subquery (see UNCACHEABLE SUBQUERY)
--sample:簡(jiǎn)單的查詢,不包含子查詢和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ǔ)句未驗(yàn)證

table

對(duì)應(yīng)行正在訪問(wèn)哪一個(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

type

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

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語(yǔ)句而且數(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:利用索引來(lái)關(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:在查詢過(guò)程中需要多個(gè)索引組合使用,沒(méi)有模擬出來(lái)
 
--ref_or_null:對(duì)于某個(gè)字段即需要關(guān)聯(lián)條件,也需要null值的情況下,查詢優(yōu)化器會(huì)選擇這種訪問(wèn)方式
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)

possible_keys

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

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

key

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

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

key_len

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

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

ref

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

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

rows

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

explain select * from emp;

extra

包含額外的信息。

--using filesort:說(shuō)明mysql無(wú)法利用索引進(jìn)行排序,只能利用排序算法進(jìn)行排序,會(huì)消耗額外的位置
explain select * from emp order by sal;
 
--using temporary:建立臨時(shí)表來(lái)保存中間結(jié)果,查詢完成之后把臨時(shí)表刪除
explain select ename,count(*) from emp where deptno = 10 group by ename;
 
--using index:這個(gè)表示當(dāng)前的查詢時(shí)覆蓋索引的,直接從索引中讀取數(shù)據(jù),而不用訪問(wèn)數(shù)據(jù)表。如果同時(shí)出現(xiàn)using where 表名索引被用來(lái)執(zhí)行索引鍵值的查找,如果沒(méi)有,表面索引被用來(lái)讀取數(shù)據(jù),而不是真的查找
explain select deptno,count(*) from emp group by deptno limit 10;
 
--using where:使用where進(jìn)行條件過(guò)濾
explain select * from t_user where id = 1;
 
--using join buffer:使用連接緩存,情況沒(méi)有模擬出來(lái)
 
--impossible where:where語(yǔ)句的結(jié)果總是false
explain select * from emp where empno = 7469;
?著作權(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),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 一、分析 數(shù)據(jù)規(guī)模限制查詢速度。在查詢前能否預(yù)先估計(jì)究竟要涉及多少行、使用哪些索引、運(yùn)行時(shí)間呢?答案是肯定的,My...
    Djbfifjd閱讀 2,558評(píng)論 0 6
  • mysql執(zhí)行計(jì)劃作為分析一條sql的執(zhí)行效率的工具十分有效,通過(guò)explain關(guān)鍵字便可查看select語(yǔ)句的具...
    SawyerZhou閱讀 13,150評(píng)論 0 11
  • mysql的開(kāi)源和使用簡(jiǎn)單使得其成為目前主流的RDB的主流數(shù)據(jù)庫(kù),但是mysql的效率相比Oracle性能上有很大...
    時(shí)之令閱讀 1,115評(píng)論 0 3
  • 引言: 實(shí)際項(xiàng)目開(kāi)發(fā)中,由于我們不知道實(shí)際查詢的時(shí)候數(shù)據(jù)庫(kù)里發(fā)生了什么事情,數(shù)據(jù)庫(kù)軟件是怎樣掃描表、怎樣使用索引的...
    chen_chen_chen_閱讀 523評(píng)論 0 0
  • 我在人生這條道上兜了一圈又一圈,走走停停,在最美的年華遇見(jiàn)了你。似乎我們心心相印,每一次含情脈脈,終于我還是忍不...
    陌涼兒閱讀 290評(píng)論 0 0

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