1. 程式人生 > >MySQL 8.0 索引特性2-索引跳躍掃描

MySQL 8.0 索引特性2-索引跳躍掃描

where mysq img strong 沒有 優化 聯合 這樣的 oracl

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 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 推出的適合聯合索引左邊列唯一值較少的情況的一種優化策略

MySQL 8.0 索引特性2-索引跳躍掃描