MySQL 中 limit 分頁偏移量過大的優化


原因

  • 查詢所有列導致回表

  • limit a, b會查詢前a+b條數據,然后丟棄前a條數據

優化方案

兩種,一般用覆蓋索引,使用條件過濾有前提限制。

1. 覆蓋索引

所謂的覆蓋索引就是從非主聚簇索引中就能查到的想要數據,而不需要通過回表從主鍵索引中查詢其他列,能夠顯著提升性能。

優化方案就是先查詢得到主鍵id,然后再根據主鍵id查詢其他列數據.

select * from user a join (select id from user where sex = 1 limit 10000000,10) b on a.id = b.id;

上面內容也許有點抽象,解釋一下,因為 sex 是有索引,這里命中 sex 索引,而其 data 存儲的是 主鍵值(即 id)那么可以直接得到,所以無需再回表。

回表: 如果查詢不是 id 或者 sex ,而是其他字段,那么還要走一遍主索引(即 id 的 B+ 樹),得到這個字段的數據。這就是回表。

詳細可以看:mysql覆蓋索引與回表

關於什么是 非聚簇索引 和 聚簇索引看:MySQL 之 非聚簇索引 和 聚簇索引

2. 條件過濾

基於排序做條件過濾,這樣的方式優化是有條件的:主鍵 id 必須是有序的。在有序的條件下,也可以使用比如創建時間等其他字段來代替主鍵 id ,但是前提是這個字段是建立了索引的。

一般使用自增主鍵的時候可以使用這個方式

select * from user where sex = 1 and id > (select id from user where sex = 1 limit 10000000, 1) limit 10;

參考

MySQL中limit分頁大偏移量的原因分析與優化方案

mysql覆蓋索引與回表

MySQL 之 非聚簇索引 和 聚簇索引


免責聲明!

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



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