MySQL 8.0 索引特性3 -倒序索引


我們今天來介紹下 MySQL 8.0 引入的新特性:倒序索引。

MySQL長期以來對索引的建立只允許正向asc存儲,就算建立了desc,也是忽略掉。

比如對於以下的查詢,無法發揮索引的最佳性能。

查詢一:

select * from tb1 where f1 = ... order by id desc;

查詢二:

select * from tb1 where f1 = ... order by f1 asc , f2 desc;

那對於上面的查詢,尤其是數據量和並發到一定峰值的時候,則對OS的資源消耗非常大。一般這樣的SQL在查詢計划里面會出現using filesort等狀態

比如針對下面的表t1,針對字段rank1有兩個索引,一個是正序的,一個是反序的。不過在MySQL 8.0 之前的版本都是按照正序來存儲

按照rank1 正向排序的執行計划,

按照rank1 反向排序的執行計划, 

 

從執行計划來看,反向比正向除了extra里多了Using temporary; Using filesort這兩個,其他的一模一樣。這兩個就代表中間用到了臨時表和排序,一般來說,凡是執行計划里用到了這兩個的,性能幾乎都不咋地。除非我這個臨時表不太大,而用於排序的buffer也足夠大,那性能也不至於太差。那這兩個選項到底對性能有多大影響呢?

 

我們分別執行這兩個查詢,並且查看MySQL的session級的status就大概能看出些許不同。

 

 通過以上兩張圖,我們發現反向的比正向的多了很多個計數,比如通過掃描的記錄數增加了10倍,而且還伴有10倍的臨時表的讀和寫記錄數。那這個開銷是非常巨大的。那以上的查詢是在MySQL 5.7 上運行的。

MySQL 8.0 給我們帶來了倒序索引(Descending Indexes),也就是說反向存儲的索引。 這里不要跟搜索引擎中的倒排索引混淆了,MySQL這里只是反向排序存儲而已。不過這個倒序存儲已經解決了很大的問題。我們再看下之前在MySQL 5.7 上運行的例子。

 我們把數據導入到MySQL 8.0,

 

 再把原來的索引變為倒序索引,

再次看下第二個SQL的查詢計划,

很顯然,用到了這個倒序索引 idx_rank1_desc,而這里的臨時表等的信息消失了

當然了,這里的組合比較多,比如我這張表的字段rank1,rank2兩個可以任意組合

組合一:

(rank1 asc,rank2 asc);

 組合二:

(rank1 desc,rank2 desc);

組合三:

(rank1 asc,rank2 desc);

組合四:

(rank1 desc,rank2 asc);

 

我把這幾個加上,適合的查詢比如:

查詢一:

Select * from t1 where rank1 = 11 order by rank2;

查詢二:

Select * from t1 where 1 order by rank1,rank2;

查詢三:

Select * from t1 where 1 order by rank1 desc,rank2;

。。。。。

等等,這里就不一一示范了! 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM