mysql的分页查询,越往后翻越慢怎么办


问题:在业务中,分页查询的场景非常多见,比如脚本分批处理数据;比如页面上需要分页查看列表。

假设是按照自增主键排序后分页,最开始的时候肯定没问题:

SELECT * from table_name order by id desc limit 0,20;
OK, Time: 0.007000s

但是如果翻到后面,情况肯定就不好了...

SELECT * from table_name order by id desc limit 10000000,20;
OK, Time: 15.588000s

具体耗时根据表的大小和数据库服务器而不同,是否能接受也看业务的具体情况,下面我们看下这种情况是为什么,以及如何优化。

explain一下慢查询语句,可以看到:

 

 

显然rows就是查询慢的罪魁祸首了,Handler_read_prev 10000019 Number of requests to read the previous row in key order. Mainly used to optimize ORDER BY ... DESC.

这里要注意,即使在有索引的情况下,limit...offset操作也会从头扫数据。

接下来是解决方案:

利用索引覆盖,可以省去回表的耗时。

SELECT * from table_name order by id desc limit 10000000,1;
OK, Time: 17.751000s
SELECT id from table_name order by id desc limit 10000000,1;
OK, Time: 5.370000s

所以改成如下SQL一般会快一些:

SELECT * from table_name where id >= (SELECT id from t_movie_schedule order by id desc limit 10000000, 1) limit 1;
OK, Time: 6.912000s

但是很迷的是上面这个SQL不太稳定,似乎没有分开执行这两个SQL快

SELECT id from table_name order by id desc limit 10000000, 1;
SELECT * from table_name where id >= (635883593) limit 1;

先忽略掉上面这个问题,也可以考虑在代码里去处理这个问题,分两步来查询。

至于为什么select id会更快,我们需要了解下聚簇索引和回表的概念,这篇博客讲得很清楚:https://www.cnblogs.com/boluopabo/p/12869348.html

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM