目錄
?前言:
explain:?
語法:
總結(jié):
?前言:
? ? ? ? 上一篇我們介紹了從時(shí)間角度分析MySQL語句執(zhí)行效率的三大工具:SQL執(zhí)行頻率,慢日志查詢,profile。但是這三個(gè)方法也只是在時(shí)間角度粗略的查看SQL語句效率,我們要想看一個(gè)語句的真正性能,還要借助explain來查看SQL語句的優(yōu)劣。
explain:?
在 SQL 中,EXPLAIN??獲取MySQL如何執(zhí)行SELECT語句的信息,包括在SELECT語句的執(zhí)行過程中表如何連接和連接的順序。
EXPLAIN?命令會(huì)模擬查詢執(zhí)行過程,而不執(zhí)行查詢本身,從而解釋查詢的執(zhí)行計(jì)劃方式以及使用的索引,有助于檢查查詢是否使用有效的索引,以及需要進(jìn)行優(yōu)化的部分。
具體而言,EXPLAIN?會(huì)生成一個(gè)表格,其中包含了查詢語句的各個(gè)部分對(duì)應(yīng)的執(zhí)行計(jì)劃,包括查詢類型、表掃描方式、索引使用情況等等。這個(gè)表格中的每一行對(duì)應(yīng)查詢過程中的一個(gè)步驟,而每一列則描述該步驟或該查詢語句的其他相關(guān)信息。
通過使用 EXPLAIN?命令,開發(fā)人員可以更好地了解查詢優(yōu)化器的使用,確定查詢中的性能問題并嘗試通過調(diào)整查詢語句、索引等來解決這些問題。
語法:
#直接在SELECT語句之前加上關(guān)鍵字explain
EXPLAIN SELECT 字段列表 FROM 表名 WHERE 條件;
我們在自建的表中使用一下這條語句:
EXPLAIN SELECT * FROM emp WHERE age BETWEEN 18 AND 30;
可以看到執(zhí)行結(jié)果為:
?我們逐一介紹這些都代表什么:
1.id:slesct查詢的序列號(hào),表示查詢中執(zhí)行select子句或者是順序表的操作(id相同,執(zhí)行順序從上到下,id不同,值越大,越先執(zhí)行)
2. select_type:? 這個(gè)字段用于指示 MySQL 執(zhí)行查詢的類型
- SIMPLE:簡單查詢,不包含 UNION 查詢或子查詢等。
- PRIMARY:表示查詢語句中最外層查詢。
- DEPENDENT SUBQUERY:依賴外部查詢中的結(jié)果。
- UNION:在 UNION 中的第二個(gè)或后續(xù) SELECT 語句。
- UNION RESULT:從 UNION 查詢的結(jié)果中選擇行。
- SUBQUERY:在 WHERE 子句或 HAVING 子句中的子查詢。
- DERIVED:為 FROM 子句中的表或子查詢派生臨時(shí)表,并用該表返回結(jié)果。
- MATERIALIZED:派生臨時(shí)表已存在,查詢需要檢索它的結(jié)果。
在給定的執(zhí)行計(jì)劃中,`select_type` 的值是 `SIMPLE`,這意味著查詢是一個(gè)簡單的查詢,沒有使用 UNION 查詢或子查詢等復(fù)雜特性。
3.type:指出查詢語句所涉及的表名以及使用的訪問方式。
所有的訪問方式:
- system:系統(tǒng)表中僅有一行的表(例如 `dual` 等),這是`const` 類型的特例,一般不需要考慮該訪問方式。
- const:表示查詢使用常數(shù)來匹配,只有一行數(shù)據(jù)滿足條件。這種情況一般出現(xiàn)在使用主鍵或唯一索引進(jìn)行查詢的情況下。
- eq_ref:使用的是唯一索引或主鍵來查詢,查詢的就是匹配的一行數(shù)據(jù)。
- ref:查詢使用非唯一索引,返回的結(jié)果集會(huì)處理一部分索引,需要回到數(shù)據(jù)表中進(jìn)行匹配查詢條件的數(shù)據(jù)。
- range:使用一個(gè) {@link https://dev.mysql.com/doc/refman/8.0/en/index-merge-optimization.html | 索引范圍查找}。
- index:表示查詢會(huì)全索引掃描,并不需要回到數(shù)據(jù)表中進(jìn)行數(shù)據(jù)查詢。
- ALL:表示全表掃描,對(duì)于大表而言,這是一種相對(duì)來說較低效的查詢方式。
這些訪問方式會(huì)影響到 MySQL 數(shù)據(jù)庫的查詢效率,因此在開發(fā)中應(yīng)該靈活根據(jù)具體情況來選擇選擇適合的查詢方式。例如,對(duì)于大表而言,應(yīng)該盡可能地使用索引進(jìn)行查詢,避免使用 `ALL` 等類型。
這些類型的性能從高到低分別為:NULL,system,const,eq_ref,ref,range,index,all.
但實(shí)際上我們查詢不會(huì)出現(xiàn)NULL的訪問方式,因?yàn)镹ULL不表示本次查詢沒有用到任何表,實(shí)際中我們再怎么優(yōu)化也不可能優(yōu)化NULL。
4.possible_keys:表示可以在該查詢中使用的索引。
5.key:實(shí)際使用的索引。
6.key_len:表示 MySQL 所使用的索引的長度。
7.ref:表示 MySQL 所使用的索引與表之間的關(guān)聯(lián)條件。
8.rows:表示 MySQL 在執(zhí)行查詢時(shí)掃描的行數(shù)。
9. filtered:表示結(jié)果集的行數(shù)與掃描的行數(shù)之間的比率。
10. Extra:表示額外的執(zhí)行計(jì)劃細(xì)節(jié)。在本例中使用了 Using where,表示該查詢使用了 WHERE 條件。
這里因?yàn)樯厦嫜菔镜臅r(shí)候使用的是單表查詢,因此只有一個(gè)select語句,無法看出id的效果,因此我們在這里調(diào)用一下多表查詢
explain select e.*, d.name from emp e left join dept d on e.dept_id = d.id;
運(yùn)行結(jié)果:
?我們在這里可以發(fā)現(xiàn):id并不是自增的,這也就是我們之前提到的
id是slesct查詢的序列號(hào),表示查詢中執(zhí)行select子句或者是順序表的操作(id相同,執(zhí)行順序從上到下,id不同,值越大,越先執(zhí)行)
如果id不同的情況呢?
explain select * from emp where dept_id = (select id from dept where name = '銷售部');
運(yùn)行結(jié)果:
?我們可以看到在這個(gè)情況下id就體現(xiàn)了執(zhí)行順序,我們可以知道在這個(gè)多表查詢中,我們是先在demp表中執(zhí)行select語句,然后在emp表中執(zhí)行select語句。
總結(jié):
本文介紹了更加實(shí)用的效率查看工具explain,以及他的各種用法,大家要熟練掌握我們目前已經(jīng)介紹的這四個(gè)語句優(yōu)劣查看工具,這樣才可以玩轉(zhuǎn)MySQL的優(yōu)化。
如果我的內(nèi)容對(duì)你有幫助,請點(diǎn)贊,評(píng)論,收藏。創(chuàng)作不易,大家的支持就是我堅(jiān)持下去的動(dòng)力!
?文章來源地址http://www.zghlxwxcb.cn/news/detail-502237.html文章來源:http://www.zghlxwxcb.cn/news/detail-502237.html
?
到了這里,關(guān)于【MySQL數(shù)據(jù)庫 | 第二十篇】explain執(zhí)行計(jì)劃的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!