Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > MySQL深分页

MySQL中深分页LIMIT 100000的优化方案

作者:程序员卷卷狗

在实际项目中,分页查询是最常见的 SQL 场景之一,但随着业务数据量不断增长,我们经常会遇到深分页的请求,本文将带大家理解 MySQL 深分页的本质以及掌握高性能替代方案,感兴趣的可以了解下

一、前言:深分页是数据库最常见的性能陷阱

大家好,我是程序员卷卷狗。

在实际项目中,分页查询是最常见的 SQL 场景之一。但随着业务数据量不断增长,我们经常会遇到类似的请求:

SELECT * FROM order LIMIT 100000, 20;

看似普通的分页,却是 MySQL 性能下降最典型的原因之一。深分页会导致大量无效扫描,使数据库压力急剧上升,严重时甚至拖垮整个系统。

理解 MySQL 深分页的本质,以及掌握高性能替代方案,是后端开发必须具备的能力。

二、深分页为什么慢:MySQL 的扫描机制决定了性能上限

MySQL 在执行 LIMIT offset, size 时,后台需要先扫描 offset+size 行,再丢弃前 offset 行,最后只返回 size 行。

例如:

LIMIT 100000, 20;

实际上 MySQL 做了:

这意味着:OFFSET 越大,MySQL 的扫描成本越高。

深分页本质上是:大量无意义的扫描与丢弃操作导致性能变差。

三、传统的 LIMIT 深分页问题实例

假设 order 表有 500 万行。

执行:

SELECT * FROM order ORDER BY id LIMIT 3000000, 20;

执行过程如下:

在 InnoDB 中,行是按主键组织的,因此需要大量磁盘随机读,性能极其低下。

四、深分页优化方案一:利用索引覆盖 + 子查询替代 OFFSET

最广泛使用的方法是:先查主键,再回查数据

示例:

SELECT * 
FROM order o 
JOIN (
    SELECT id 
    FROM order 
    ORDER BY id 
    LIMIT 100000, 20
) tmp ON o.id = tmp.id;

优势:

这是后端分页中最通用的优化方式。

五、深分页优化方案二:基于主键条件的“游标式分页”

核心思想:只查询比上一页最后一条记录大的数据

示例:

SELECT * 
FROM order 
WHERE id > #{lastId} 
ORDER BY id 
LIMIT 20;

效果:

适用于:

这是现代后端系统最推荐的分页方式。

六、深分页优化方案三:使用延迟关联减少扫描

对于关联查询,可以先通过索引获取主键,再做回表关联。

示例:

SELECT o.* 
FROM order o 
JOIN (
    SELECT id 
    FROM order 
    WHERE status = 1
    ORDER BY id
    LIMIT 100000, 20
) t ON o.id = t.id;

优点:

适用于:

七、深分页优化方案四:反向分页

如果用户想看最后几页:

SELECT * FROM order ORDER BY id DESC LIMIT 20 OFFSET 100000;

可以转换为:

SELECT * 
FROM order 
ORDER BY id ASC 
LIMIT total - 100000 - 20, 20;

减少扫描量,提升性能。

适用于:

八、深分页优化方案五:通过业务改造避免深分页

包括:

深分页本质上是业务问题,避免深分页比优化深分页更高效。

九、面试高频问题与标准回答

问:MySQL 为什么深分页会慢?

答:LIMIT offset,size 会导致 MySQL 实际扫描 offset+size 行,再丢弃前 offset 行,随着 offset 增大,会出现大量无效扫描,磁盘 I/O 和 CPU 消耗急剧增加。

问:如何优化 LIMIT 100000,20?

答:可以通过索引覆盖查询、延迟关联、主键游标分页等方式,将 OFFSET 分离为基于主键或索引的范围过滤,从而避免大量无效扫描。

问:游标分页的原理是什么?

答:通过记录上一页的最大主键,将下一页限制为 WHERE id > lastId 的形式,使分页不再依赖 OFFSET,提高查询效率。

问:什么时候必须放弃 MySQL 分页?

答:当查询数据量非常巨大且业务允许时,可以将搜索功能迁移到 Elasticsearch 或 ClickHouse,提高深分页性能。

十、总结

深分页的性能问题来自 MySQL 扫描机制本身,而不是 SQL 写得好坏。

真正的解决方案在于:

一句话总结:

深分页的关键不是查询更多数据,而是避免不必要的扫描。

到此这篇关于MySQL中深分页LIMIT 100000的优化方案的文章就介绍到这了,更多相关MySQL深分页内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文