新聞中心
這篇文章主要介紹“分析MySQL EXPLAIN結(jié)果集”,在日常操作中,相信很多人在分析MySQL EXPLAIN結(jié)果集問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”分析MySQL EXPLAIN結(jié)果集”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
EXPLAIN:查看SQL語句的執(zhí)行計劃
EXPLAIN命令可以幫助我們深入了解MySQL基于開銷的優(yōu)化器,還可以獲得很多可能被優(yōu)化器考慮到的訪問策略的細節(jié),以及當運行SQL語句時哪種策略預(yù)計會被優(yōu)化器采用,在優(yōu)化慢查詢時非常有用
執(zhí)行explain之后結(jié)果集包含如下信息
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-------+
下面將對每一個值進行解釋
1、id
id用來標識整個查詢中SELELCT語句的順序,在嵌套查詢中id越大的語句越先執(zhí)行,該值可能為NULL
id如果相同,從上往下依次執(zhí)行。id不同,id值越大,執(zhí)行優(yōu)先級越高,如果行引用其他行的并集結(jié)果,則該值可以為NULL
2、select_type
select_type表示查詢使用的類型,有下面幾種:
simple:
列類型 | 長度 | 備注 |
---|---|---|
id int | 4+1 | int為4bytes,允許為NULL,加1byte |
id bigint not null | 8 | bigint為8bytes |
user char(30) utf8 | 30*3+1 | utf8每個字符為3bytes,允許為NULL,加1byte |
user varchar(30) not null utf8 | 30*3+2 | utf8每個字符為3bytes,變長數(shù)據(jù)類型,加2bytes |
user varchar(30) utf8 | 30*3+2+1 | utf8每個字符為3bytes,允許為NULL,加1byte,變長數(shù)據(jù)類型,加2bytes |
detail text(10) utf8 | 30*3+2+1 | TEXT截取部分,被視為動態(tài)列類型。 |
key_len只指示了where中用于條件過濾時被選中的索引列,是不包含order by
或group by
這一部分被選中的索引列
8、ref
ref列用來顯示使用哪個列或常數(shù)與key一起從表中選擇相應(yīng)的行。它顯示的列的名字(或const),此列多數(shù)時候為null
9、rows
rows列顯示的是mysql解析器認為執(zhí)行此SQL時必須掃描的行數(shù)。此數(shù)值為一個預(yù)估值,不是具體值,通常比實際值小
10、filtered
此參數(shù)為mysql 5.7 新加參數(shù),指的是返回結(jié)果的行數(shù)所占需要讀到的行(rows的值)的比例
對于使用join時,前一個表的結(jié)果集大小直接影響了循環(huán)的行數(shù)
11、extra(重要)
extra表示不在其他列并且也很重要的額外信息
using index: 該值表示這個SQL語句使用了覆蓋索引(覆蓋索引是指可以直接在索引列中得到想要的結(jié)果,而不用去回表),此時效率最高
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 |
+----+-------------+-------+-------+---------------+----------+---------+------+-------+-------------+
這個例子中id
字段為主鍵,但是key那里顯示走的并不是主鍵索引,這個是因為mysql的所有二級索引中都會包含所有的主鍵信息,而mysql沒有單獨的存儲主鍵索引,所以掃描二級索引的開銷比全表掃描更快
using where: 表示存儲引擎搜到記錄后進行了后過濾(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需要使用臨時表來存儲結(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無法利用索引直接完成排序(排序的字段不是索引字段),此時會用到緩沖空間來進行排序
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: 強調(diào)在獲取連接條件時沒有用到索引,并且需要連接緩沖區(qū)來存儲中間結(jié)果。(性能可以通過添加索引或者修改連接字段改進)
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)的每一行與整個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)化了可以在索引(僅限二級索引)上進行 like 查找
如果extra中出現(xiàn)多個上面結(jié)果,則表示順序使用上面的方法進行解析查詢
到此,關(guān)于“分析MySQL EXPLAIN結(jié)果集”的學習就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關(guān)知識,請繼續(xù)關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
本文題目:分析MySQLEXPLAIN結(jié)果集-創(chuàng)新互聯(lián)
標題來源:http://fisionsoft.com.cn/article/ccjhep.html