CAS
589
2025-04-01
Extra
提示執(zhí)行計(jì)劃的一些額外信息
1 No tables used
當(dāng)查詢中沒有from子句,會提示該字眼
explain select @@server_uuid
2 Impossible Where
查詢語句中where子句用于為false時(shí) 提示該信息
explain select * from s1 where 1 < 0
3 No matching min/max row
當(dāng)查詢 有使用 MIN / MAX 聚集函數(shù),單沒有記錄符合 where子句中的搜索條件時(shí), 將會提示該信息
explain select min(key1) from s1 where key1="alex"
4 Using index
使用 覆蓋索引執(zhí)行查詢時(shí),僅通過掃描索引數(shù)即可 不需要回表 extra會打印 using index
explain select key1 from s1 where key1 = "alex";
5 Using index condition
有些搜索條件雖然出現(xiàn)了索引列 但不能充當(dāng)邊界條件來形成掃描區(qū)間, 就不能用來減少掃描的記錄,但MySQL做了優(yōu)化 index condition pushdown 來減少掃描聚簇索引
explain select key1 from s1 where key1 > "a" and key1 like "%a";
6 Using index condition
有些搜索條件雖然出現(xiàn)了索引列 但不能充當(dāng)邊界條件來形成掃描區(qū)間, 就不能用來減少掃描的記錄,但MySQL做了優(yōu)化 index condition pushdown 來減少掃描聚簇索引
explain select key1 from s1 where key1 > "a" and key1 like "%a";
Index condition? pushdown 索引下推
雖然 where key1 like “%a” 不能充當(dāng)邊界條件來減少掃描二級索引記錄,但是where條件中僅涉及 key1 ; MySQL做了如下優(yōu)化
1 server層調(diào)用 innodb接口定位到滿足 key1 > “a” 的第一條二級索引記錄
2 innodb 根據(jù)二級索引找到第一條記錄后,并不急于回表, 而是判斷 key1 like "%a" 是否成立,如果不成立跳過,成立回表取所有數(shù)據(jù) 返回server
3 server層判斷其它條件 是否滿足
綜上: 如果每次掃描到第一條條件就回表 加載數(shù)據(jù)頁,這樣耗費(fèi)性能, 做了不著急回表 在索引B數(shù)上判斷其它條件,如果滿足就回表
索引條件下推特性只是為了在掃描某個(gè)掃描區(qū)間的二級索引記錄時(shí),盡可能減少回表操作次數(shù),減少IO操作,如果對于聚簇索引,不需要回表,起不到減少IO操作
7 Using where
當(dāng)某個(gè)搜索條件需要在server層進(jìn)行判斷,extra列就會提示 using where
explain select * from s1 where key1 = "a" and key3 = "cc";
8 Using join buffer(Block Nested Loop)
當(dāng)被驅(qū)動表不能有效利用索引, mysql會利用 連接緩沖區(qū)(join buffer) 內(nèi)存來加速查詢, 也是基于嵌套查詢
# using join buffer 對于 被驅(qū)動表S2 沒用到索引, 使用where 是因?yàn)閷?yīng)s2 where s2.commen_field= 一個(gè)常數(shù) 需要在server層進(jìn)行判斷
explain select * from s1 join s2 on s1.commen_field = s2.commen_field
9 Using intersect() ?using union() using sort union()
如果出現(xiàn)了 using intersect() 意味著優(yōu)化器對索引進(jìn)行了合并,減少檢索范圍
explain select * from s2 where key1 = "a" or key3 = "a";
10 Zero limit
當(dāng)limit 子句參數(shù)為0, 表示壓根不打算從表中讀出任何記錄,會提示 zero limit
explain select * from s2 where? key1 = "a" or key3 = "a" limit 0;
11?Using filesort? Using temporary
對結(jié)果集需要進(jìn)行排序,且無法使用到索引,就需要在內(nèi)存中 或者 磁盤上利用臨時(shí)文件對結(jié)果集進(jìn)行排序, 內(nèi)存/磁盤上排序稱為filesort , 如果過程中使用到了臨時(shí)表 就是using temporary
explain select * from s2 order by s2.commen_field
有時(shí)候mysql會利用臨時(shí)表完成排序,去重,分組等功能, 例 distinct, group by, union 等,且無法有效利用索引,就用內(nèi)部臨時(shí)表 會出現(xiàn)using temporary
explain select count(*) commen_field from s2 GROUP BY s2.commen_field
注意
有時(shí)候 using filesort 和 using temporary 同時(shí)出現(xiàn), 是因?yàn)閙ysql 默認(rèn)給 group by 后面添加了 order by 子句; 實(shí)際生產(chǎn)中根據(jù)實(shí)際情況進(jìn)行設(shè)計(jì)
explain select count(*) commen_field from s2? GROUP BY s2.commen_field? ORDER BY s2.commen_field
IN 轉(zhuǎn)為 半連接 對應(yīng)的 extra信息
12?Start temporary , end temporary
Start temporary , end temporary
優(yōu)化器會嘗試將in 轉(zhuǎn)成半連接, 當(dāng)策略為 duplicate_Weedout時(shí)(通過創(chuàng)建臨時(shí)表方式為外層查詢中的記錄進(jìn)行去重操作) 驅(qū)動表執(zhí)行計(jì)劃對應(yīng)extra為start temporary, 被驅(qū)動表為 end temporary
explain select * from s1 where key2 in (SELECT key2 from s2 where s2.commen_field = "alex") # 其實(shí)優(yōu)化器將SQL 優(yōu)化成 select * from s1 semi join s2 on s1.key2 = s2.key2 where s2.commen_field = "alex" 將s2 當(dāng)成了驅(qū)動表
13 looseScan
將in 子查詢 轉(zhuǎn)成 semi join ,如果采用looseScan (雖然是掃描索引,但只取鍵值相同的第一條記錄去匹配) 則驅(qū)動表執(zhí)行計(jì)劃 extra 顯示looseScan
# 轉(zhuǎn)成semi join? select * from s1 semi join s2 on ?s1.key3= s2.key1 where s2.key1 like “a%”
# 轉(zhuǎn)成semi join 后 s2 作為驅(qū)動表; 基于索引 key1檢索中結(jié)果集符合 s2.key1 like “a%” 可能有 3865條,例 aalex aalex abob abob, 再做代入內(nèi)層循環(huán)時(shí)候,只會取第一個(gè) s2.key1 =aalex 作為條件代入 內(nèi)層循環(huán)去判斷 是否能在 s1 找到對應(yīng)的記錄,如果能找到就返回結(jié)果集,不能找到則進(jìn)行下一次判斷
備注: 只會取鍵值相同的第一條記錄去進(jìn)行判斷
explain select * from s1 where s1.key3 in (SELECT key1 from s2 where s2.key1 like "a%" )
14 FirstMatch(tableName)
首次匹配時(shí)最原始的semi join 執(zhí)行方式, 先去外層查詢一條記錄, 然后到子查詢中尋找服務(wù)匹配條件的記錄
# s2 是子查詢 意味著會被執(zhí)行多次 且要判斷是否符合外層傳入的列值
explain select * from s1 where s1.commen_field in (SELECT key1 from s2 where s2.key1 = s1.key1)
MySQL
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。