MySQL深分页优化:游标分页 vs 延迟关联 vs 子查询,实测对比MySQL

背景与问题

在业务系统中,分页查询是最常见的数据库操作之一。然而,当数据量达到百万级,使用传统的 LIMIT offset, size 进行深分页(如 LIMIT 1000000, 20)时,性能会急剧下降。原因在于 MySQL 需要扫描并丢弃前 offset 行,才能返回目标数据,这种全表扫描的代价随 offset 增大而线性增长。

本文将以一个实际订单表(500万行数据)为例,对比三种主流优化方案:游标分页延迟关联子查询优化,并给出实测数据与适用场景。

方案一:游标分页(基于排序键)

核心思想:不指定 offset,而是记住上一页最后一条记录的排序键值,查询时用 WHERE id > last_id 定位。

复制代码
-- 第一页
SELECT * FROM orders ORDER BY id LIMIT 20;
-- 下一页,传入上一页最后一条记录的 id
SELECT * FROM orders WHERE id > 1000000 ORDER BY id LIMIT 20;

优点:性能恒定,与页码无关;索引利用率高;代码简单。

缺点:只能按单一排序字段(通常是主键)进行;无法实现跳页(如直接跳到第100页);如果排序字段有重复值,需要额外处理。

适用场景:无限滚动、移动端加载更多、API 分页。

方案二:延迟关联(覆盖索引 + 回表)

核心思想:先通过覆盖索引快速定位所需行的主键,再与原表关联获取完整数据。

复制代码
SELECT o.* FROM orders o
INNER JOIN (
    SELECT id FROM orders ORDER BY id LIMIT 1000000, 20
) AS tmp ON o.id = tmp.id;

优点:避免了全行扫描,只扫描索引;相比传统 LIMIT 性能提升明显。

缺点:仍然需要扫描 offset 行(但只扫索引),offset 很大时性能依然下降;需要额外 join 操作。

适用场景:需要跳页,且排序字段有索引(不一定是主键)时。

方案三:子查询优化(基于索引覆盖)

核心思想:先通过子查询快速定位起始位置,再取后续数据。

复制代码
SELECT * FROM orders
WHERE id >= (SELECT id FROM orders ORDER BY id LIMIT 1000000, 1)
ORDER BY id
LIMIT 20;

优点:无需 join,单次查询;相比延迟关联更简洁。

缺点:子查询仍需要扫描 offset 行;依赖主键或唯一索引。

适用场景:适合单表查询,且排序字段为主键时。

实测对比(500万行数据)

测试环境:MySQL 8.0,InnoDB,订单表 500 万行,主键 id。查询 LIMIT 1000000, 20

方案 执行时间(ms) 扫描行数
传统 LIMIT 482 1000020
延迟关联 126 1000020(索引)
子查询优化 98 1000020(索引)
游标分页 2 20

可见,游标分页性能最优,但牺牲了跳页能力;延迟关联和子查询优化能缓解深分页问题,但 offset 很大时依然有性能瓶颈。

总结与选型建议

  • 优先使用游标分页:如果你的业务允许(如无限滚动、加载更多),这是性能最好的方案。
  • 需要跳页时:使用延迟关联或子查询优化,并确保排序字段有索引。
  • 避免过深 offset:如果业务必须跳页,可以考虑限制最大页码,或使用缓存。

最后,无论哪种方案,都应配合索引优化和查询分析(EXPLAIN)进行验证,切勿盲目套用。

相关推荐
liferecords2 天前
第 6 讲 · KSYS 实战:用数据定位瓶颈,而不是靠猜
性能调优·性能分析·鲲鹏·ksys·devkit
gwf2166 天前
NVMe/RDMA传输层协议深度解析:RDMA原理、Queue Pair映射、内核实现与性能全栈剖析
linux内核·ssd·nvme·性能调优·rdma·存储协议·nvme/rdma
gwf2168 天前
NVMe/TCP传输层协议深度解析:PDU格式、内核实现、性能调优全栈剖析
linux内核·ssd·nvme·性能调优·nvme-of·存储协议·nvme/tcp
智码看视界25 天前
Spark 3.5 AQE 调优:10 个生产环境案例让作业提速 3-10 倍
大数据·spark·性能调优·aqe·sparksql·数据倾斜·etl优化
七夜zippoe1 个月前
基于 DolphinDB 2.x 的系统性能调优实战:从监控、分析到优化验证的全链路指南
性能调优·监控·分析·dolphindb·优化验证
张永清1 个月前
每周读书与学习->张永清性能测试知识体系
性能测试·性能调优·jmeter性能测试·性能分析·性能监控·每周读书与学习
云边有个稻草人2 个月前
金仓数据库技术解析:`WHERE` 里的条件,谁先执行真不是看谁写在前面
性能调优·sql优化·执行计划·金仓数据库·数据库优化器·where子句
云边有个稻草人4 个月前
金仓数据库标量子查询消除:解决复杂SQL性能瓶颈
数据库·sql·性能调优·金仓数据库·kes·标量子查询·数据库内核
数据与后端架构提升之路4 个月前
深度学习性能调优全景指南:数据、计算、显存、通信四大瓶颈的破局之道
深度学习·gpu·性能调优