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