溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

分析MySQL EXPLAIN結(jié)果集

發(fā)布時(shí)間:2021-11-08 10:28:11 來(lái)源:億速云 閱讀:144 作者:iii 欄目:MySQL數(shù)據(jù)庫(kù)

這篇文章主要介紹“分析MySQL EXPLAIN結(jié)果集”,在日常操作中,相信很多人在分析MySQL EXPLAIN結(jié)果集問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”分析MySQL EXPLAIN結(jié)果集”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

EXPLAIN:查看SQL語(yǔ)句的執(zhí)行計(jì)劃

EXPLAIN命令可以幫助我們深入了解MySQL基于開銷的優(yōu)化器,還可以獲得很多可能被優(yōu)化器考慮到的訪問策略的細(xì)節(jié),以及當(dāng)運(yùn)行SQL語(yǔ)句時(shí)哪種策略預(yù)計(jì)會(huì)被優(yōu)化器采用,在優(yōu)化慢查詢時(shí)非常有用

執(zhí)行explain之后結(jié)果集包含如下信息

+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows   | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-------+

下面將對(duì)每一個(gè)值進(jìn)行解釋

1、id

id用來(lái)標(biāo)識(shí)整個(gè)查詢中SELELCT語(yǔ)句的順序,在嵌套查詢中id越大的語(yǔ)句越先執(zhí)行,該值可能為NULL

id如果相同,從上往下依次執(zhí)行。id不同,id值越大,執(zhí)行優(yōu)先級(jí)越高,如果行引用其他行的并集結(jié)果,則該值可以為NULL

2、select_type

select_type表示查詢使用的類型,有下面幾種:

simple:

列類型長(zhǎng)度備注
id int4+1int為4bytes,允許為NULL,加1byte
id bigint not null8bigint為8bytes
user char(30) utf830*3+1utf8每個(gè)字符為3bytes,允許為NULL,加1byte
user varchar(30) not null utf830*3+2utf8每個(gè)字符為3bytes,變長(zhǎng)數(shù)據(jù)類型,加2bytes
user varchar(30) utf830*3+2+1utf8每個(gè)字符為3bytes,允許為NULL,加1byte,變長(zhǎng)數(shù)據(jù)類型,加2bytes
detail text(10) utf830*3+2+1TEXT截取部分,被視為動(dòng)態(tài)列類型。

key_len只指示了where中用于條件過濾時(shí)被選中的索引列,是不包含order bygroup by這一部分被選中的索引列

8、ref

ref列用來(lái)顯示使用哪個(gè)列或常數(shù)與key一起從表中選擇相應(yīng)的行。它顯示的列的名字(或const),此列多數(shù)時(shí)候?yàn)閚ull

9、rows

rows列顯示的是mysql解析器認(rèn)為執(zhí)行此SQL時(shí)必須掃描的行數(shù)。此數(shù)值為一個(gè)預(yù)估值,不是具體值,通常比實(shí)際值小

10、filtered

此參數(shù)為mysql 5.7 新加參數(shù),指的是返回結(jié)果的行數(shù)所占需要讀到的行(rows的值)的比例
對(duì)于使用join時(shí),前一個(gè)表的結(jié)果集大小直接影響了循環(huán)的行數(shù)

11、extra(重要)

extra表示不在其他列并且也很重要的額外信息

using index: 該值表示這個(gè)SQL語(yǔ)句使用了覆蓋索引(覆蓋索引是指可以直接在索引列中得到想要的結(jié)果,而不用去回表),此時(shí)效率最高

mysql> explain select id from test;
+----+-------------+-------+-------+---------------+----------+---------+------+-------+-------------+
| id | select_type | table | type  | possible_keys | key      | key_len | ref  | rows  | Extra       |
+----+-------------+-------+-------+---------------+----------+---------+------+-------+-------------+
|  1 | SIMPLE      | test  | index | NULL          | idx_bnet | 9       | NULL | 68505 | Using index |
+----+-------------+-------+-------+---------------+----------+---------+------+-------+-------------+

這個(gè)例子中id字段為主鍵,但是key那里顯示走的并不是主鍵索引,這個(gè)是因?yàn)閙ysql的所有二級(jí)索引中都會(huì)包含所有的主鍵信息,而mysql沒有單獨(dú)的存儲(chǔ)主鍵索引,所以掃描二級(jí)索引的開銷比全表掃描更快

using where: 表示存儲(chǔ)引擎搜到記錄后進(jìn)行了后過濾(POST-FILTER),如果查詢未能使用索引,using where的作用只是提醒我們mysql要用where條件過濾結(jié)果集

mysql> explain select * from test where id > 1;
+----+-------------+-------+-------+---------------+---------+---------+------+-------+-------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows  | Extra       |
+----+-------------+-------+-------+---------------+---------+---------+------+-------+-------------+
|  1 | SIMPLE      | test  | range | PRIMARY       | PRIMARY | 8       | NULL | 34252 | Using where |
+----+-------------+-------+-------+---------------+---------+---------+------+-------+-------------+

using temporary 表示mysql需要使用臨時(shí)表來(lái)存儲(chǔ)結(jié)果集,常見于排序和分組查詢

mysql> explain select * from test where id in (1,2) group by bnet_id;
+----+-------------+-------+-------+-----------------------------------------+---------+---------+------+------+----------------------------------------------+
| id | select_type | table | type  | possible_keys                           | key     | key_len | ref  | rows | Extra                                        |
+----+-------------+-------+-------+-----------------------------------------+---------+---------+------+------+----------------------------------------------+
|  1 | SIMPLE      | test  | range | PRIMARY,IDX(event_key-bnet_Id),idx_bnet | PRIMARY | 8       | NULL |    2 | Using where; Using temporary; Using filesort |
+----+-------------+-------+-------+-----------------------------------------+---------+---------+------+------+----------------------------------------------+

using filesort: 是指mysql無(wú)法利用索引直接完成排序(排序的字段不是索引字段),此時(shí)會(huì)用到緩沖空間來(lái)進(jìn)行排序

mysql> explain select * from test order by bnet_id;
+----+-------------+-------+------+---------------+------+---------+------+-------+----------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows  | Extra          |
+----+-------------+-------+------+---------------+------+---------+------+-------+----------------+
|  1 | SIMPLE      | test  | ALL  | NULL          | NULL | NULL    | NULL | 68505 | Using filesort |
+----+-------------+-------+------+---------------+------+---------+------+-------+----------------+

using join buffer: 強(qiáng)調(diào)在獲取連接條件時(shí)沒有用到索引,并且需要連接緩沖區(qū)來(lái)存儲(chǔ)中間結(jié)果。(性能可以通過添加索引或者修改連接字段改進(jìn))

mysql> explain select * from test left join test2 on test.create_time = test2.create_time;
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+----------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows   | filtered | Extra                                              |
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+----------------------------------------------------+
|  1 | SIMPLE      | test  | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 959692 |   100.00 | NULL                                               |
|  1 | SIMPLE      | test2 | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 958353 |   100.00 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+----------------------------------------------------+
2 rows in set, 1 warning (0.00 sec)

Block Nested Loop是指Block Nested-Loop Join算法:將外層循環(huán)的行/結(jié)果集存入join buffer, 內(nèi)層循環(huán)的每一行與整個(gè)buffer中的記錄做比較,從而減少內(nèi)層循環(huán)的次數(shù).

impossible where: 表示where條件導(dǎo)致沒有返回的行

mysql> explain select * from test where id is null;
+----+-------------+-------+------+---------------+------+---------+------+------+------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra            |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------+
|  1 | SIMPLE      | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | Impossible WHERE |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------+

using index condition: 是mysql 5.6 之后新加的特性,結(jié)合mysql的ICP(Index Condition Pushdown)特性使用。主要是優(yōu)化了可以在索引(僅限二級(jí)索引)上進(jìn)行 like 查找

如果extra中出現(xiàn)多個(gè)上面結(jié)果,則表示順序使用上面的方法進(jìn)行解析查詢

到此,關(guān)于“分析MySQL EXPLAIN結(jié)果集”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI