MySQL 8.0 實現了Index skip scan,翻譯過來就是索引跳躍掃描。熟悉ORACLE的朋友是否是發現愈來愈像ORACLE了?再者,熟悉MySQL 5.7 的朋友是否是以爲這個很相似當時優化器的選項MRR?好了,先具體說下什麼 ISS,我後面所有用 ISS 簡稱。ide
*考慮如下的場景:優化
表t1有一個聯合索引idx_u1(rank1,rank2),可是查詢的時候卻沒有rank1這列,只有rank2。好比,select * from t1 where rank2 = 30。spa
那之前遇到這樣的狀況,若是沒有針對rank2這列單獨創建普通索引,這條SQL怎麼着都是走的FULL TABLE SCAN。翻譯
ISS 就是在這樣的場景下產生的。ISS 能夠在查詢過濾組合索引不包括最左列的狀況下,走索引掃描,而沒必要要單獨創建額外的索引。由於畢竟額外的索引對寫開銷很大,能省則省。3d
仍是拿剛纔的例子來說,假設:blog
表t1的兩個字段rank1,rank2。有這樣的記錄,索引
rank1, rank21 1001 2001 3001 4001 5001 6001 7005 1005 2005 3005 4005 500
咱們給出的SQL是,
圖片
select * from t1 where rank2 >400,
那MySQL經過ISS把這條SQL變爲,
ip
select * from t1 where rank1=1 and rank2 > 400union allselect * from t1 where rank1 = 5 and rank2 > 400;
能夠看出來,MySQL其實內部本身把左邊的列作了一次DISTINCT,完了加進去。ci
咱們拿實際的例子來看下。假設:
仍是剛纔描述那張表,rank1字段值的distinct值比較少。查詢計劃的對比,
關閉 ISS,
很顯然,ISS 掃描的行數要比以前的少不少。
ISS其實剛好適合在這種左邊字段的惟一值較少的狀況下,效率來的高。好比性別,狀態等等。
那假設:rank1字段的distinct值比較多呢?
咱們從新造了點數據,此次,rank1的惟一值個數有快上萬個。
咱們來再次看一遍這樣SQL的執行計劃,
此次咱們發現,不管如何MySQL也不會選擇 ISS,而選了FULL INDEX SCAN。
那這樣的場景就必須給rank2加一個單獨索引了。
那來總結下 ISS 就是一句話:ISS 其實就是MySQL 8.0推出的適合聯合索引左邊列惟一值較少的狀況的一種優化策略。