引言
日常工作中调窍,使用MySQL
的機(jī)會(huì)還是蠻多的低淡,主要考慮Schema與數(shù)據(jù)類型優(yōu)化台谢、如何創(chuàng)建索引寻狂、根據(jù)業(yè)務(wù)場(chǎng)景的查詢優(yōu)化。這些想必大家都在高性能MySQL
這本書中看過朋沮,可能也比作者理解的深荆虱,本文旨在對(duì)EXPLAIN
語句使用、分析進(jìn)行整理。
EXPLAIN
語句是什么怀读?
官網(wǎng)對(duì)于EXPLAIN
的作用定義如下:
The EXPLAIN statement provides information about how MySQL executes statements. EXPLAIN works with SELECT, DELETE, INSERT, REPLACE, and UPDATE statements.
簡單來講,EXPLAIN
語句告訴我們MySQL如何執(zhí)行SQL語句骑脱,而我們通過這些信息菜枷,可以達(dá)到優(yōu)化SQL語句執(zhí)行效率的目的。
接下來叁丧,就要對(duì)EXPLAIN
返回的格式進(jìn)行了解了啤誊,具體如下:
字段名 | 字段描述 |
---|---|
id | 查詢語句內(nèi)SELECT的序列號(hào) |
select_type | SELECT類型 |
table | 訪問的表名 |
partitions | 命中分區(qū) |
type | 數(shù)據(jù)訪問類型,下文詳細(xì)介紹 |
possible_keys | 有關(guān)索引拥娄,實(shí)際情況可能不可用 |
key | MySQL查詢優(yōu)化器實(shí)際使用的索引 |
key_len | 索引存儲(chǔ)長度 |
ref | 實(shí)際使用的索引中蚊锹,用于比較的常量或列 |
rows | 查詢需要讀取的行數(shù),innodb引擎是一個(gè)衡量效率的指標(biāo)稚瘾,有時(shí)可能不準(zhǔn)確 |
Extra | 查詢執(zhí)行的附加信息牡昆,下文詳細(xì)介紹 |
在分析SQL語句執(zhí)行時(shí),主要用到的列摊欠,分別為
type
丢烘、Extra
,下文的測(cè)試用例均為官網(wǎng)提供的sakila
數(shù)據(jù)庫些椒,附上下載鏈接播瞳。本文使用MySQL 8.0.12、Navicat 12.1
type列主要出現(xiàn)值(性能從好到差)
- system:表只有一行免糕,const類型的特殊情況赢乓。
- const:查詢結(jié)果最多有一行,多為主鍵石窑、唯一索引與常量比較的情況牌芋。
explain select * from actor where actor_id = 1
- eq_ref:一種特殊的索引查找,MySQL知道最多只返回一條符合條件的記錄尼斧,使用主鍵姜贡、NOT NULL的唯一索引會(huì)看到(用navicat發(fā)現(xiàn)結(jié)果也是ref)。
explain select * from actor, film_actor where actor.actor_id = film_actor.actor_id and actor.actor_id = 1
- ref:一種索引查找棺棵,返回所有匹配某個(gè)單個(gè)值的行楼咳,然而,可能會(huì)找到多個(gè)符合條件的行烛恤,當(dāng)使用非唯一性索引或者唯一性索引的非唯一性前綴時(shí)發(fā)生母怜。
explain select * from film where title= 'ACE GOLDFINGER'
- range:范圍掃描就是一個(gè)有限制的索引掃描, 不用遍歷所有索引缚柏,例如索引在
BETWEEN
苹熏、>
、>
范圍內(nèi)的。
explain select * from film where film_id BETWEEN 1 AND 100
- index:全表掃描轨域,只是MySQL掃描表時(shí)按索引次序而不是行袱耽。
Extra列中看到“Using index”,說明是覆蓋索引干发,只需要讀取索引列朱巨,不需要讀取行數(shù)據(jù)。
使用索引次序全表讀取枉长。
explain select actor.actor_id from film_actor, actor where film_actor.actor_id = actor.actor_id
- ALL:全表掃描冀续,讀取行數(shù)據(jù),找到需要的行必峰。
explain select * from film_actor, actor where film_actor.actor_id = actor.actor_id
Extra列主要出現(xiàn)的值
- Using index:使用覆蓋索引洪唐,避免回表查詢行數(shù)據(jù)。
- Using where:存儲(chǔ)引擎檢索行后再進(jìn)行過濾吼蚁。
- Using temporary:對(duì)查詢結(jié)果排序時(shí)會(huì)使用一個(gè)臨時(shí)表凭需,盡量避免使用臨時(shí)表。
- Using filesort:對(duì)結(jié)果使用一個(gè)外部索引排序桂敛,而不是按索引次序從表里讀取行功炮,需要進(jìn)行優(yōu)化。
總結(jié)
由于查詢優(yōu)化器的存在术唬,實(shí)際運(yùn)行查詢語句會(huì)和想的不一致薪伏,因此在進(jìn)行查詢語句優(yōu)化時(shí),最好運(yùn)行下EXPLAIN
語句粗仓,看看是不是和自己想的一致嫁怀。