MySQL 8.0 索引特性2-索引跳躍掃描
MySQL 8.0 實現了Index skip scan,翻譯過來就是索引跳躍掃描。熟悉ORACLE的朋友是不是發現越來越像ORACLE了?再者,熟悉 MySQL 5.7 的朋友是不是覺得這個很類似當時優化器的選項MRR?好了,先具體說下什麽 ISS,我後面全部用 ISS 簡稱。
*考慮以下的場景:
表t1有一個聯合索引idx_u1(rank1,rank2), 但是查詢的時候卻沒有rank1這列,只有rank2。
比如,select * from t1 where rank2 = 30.那以前遇到這樣的情況,如果沒有針對rank2這列單獨建立普通索引,這條SQL怎麽著都是走的FULL TABLE SCAN。ISS就是在這樣的場景下產生的。ISS 可以在查詢過濾組合索引不包括最左列的情況下,走索引掃描,而不必要單獨建立額外的索引。
還是那剛才的例子來講,假設:
表t1的兩個字段rank1,rank2。
有這樣的記錄,
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 * from t1 where rank1=1 and rank2 > 400 union allselect * 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 推出的適合聯合索引左邊列唯一值較少的情況的一種優化策略
MySQL 8.0 索引特性2-索引跳躍掃描