mysql深度分页的几种解决方案

 更新时间:2025年09月05日 09:57:58   作者:青秋.  
MySQL深分页需避免OFFSET,改用WHERE条件定位起点,常用游标分页、延迟关联或覆盖索引优化,结合缓存可提升性能,本文主要介绍了mysql深度分页的几种解决方案,感兴趣的可以了解一下

MySQL 解决深度分页(Deep Pagination)的核心思想是“丢掉 OFFSET,用条件定位起点”,从而避免大偏移量带来的全表扫描和大量回表。常见优化方案如下:

游标/范围分页(推荐)

原理:记住上一页最后一条记录的主键(或排序列),作为下一页的起始条件。
示例

-- 上一页最后一条 id = 100000
SELECT * FROM t_order
WHERE id > 100000        -- 无 OFFSET
ORDER BY id
LIMIT 10;
  • 优点:直接跳到100000,性能稳定,不随页码增大而衰减;千万级数据仍可毫秒级返回。
  • 缺点:只能顺序翻页,不能随机跳页;需要排序列唯一且连续。

延迟关联(JOIN 子查询)

原理先用覆盖索引在子查询里拿到主键,再回表取完整行,减少大 OFFSET 的回表量。
示例

SELECT t1.*
FROM t_order t1
JOIN (SELECT id
      FROM t_order
      WHERE create_time > '2023-01-01'
      ORDER BY create_time
      LIMIT 4500000, 10) t2 ON t1.id = t2.id;
  • 优点:比直接 LIMIT 4500000,10 (该方法先数4500000条数据,然后丢掉,)少读 450w 行数据。
  • 注意:子查询里的列必须被索引覆盖,否则仍可能全表扫描。

覆盖索引 + 子查询定位起点

原理:先用覆盖索引查出第 N 条记录的排序列值,再用该值作为条件取后 10 条。
示例

-- 1. 查出第 4500000 行的 create_time
SELECT create_time
FROM t_order
ORDER BY create_time
LIMIT 4500000, 1;
 
-- 2. 用该 create_time 作为起点
SELECT *
FROM t_order
WHERE create_time >= <上一步的值>
ORDER BY create_time
LIMIT 10;
  • 优点:避免大 OFFSET;支持非主键排序。
  • 注意:排序列必须有索引,否则第 1 步也会很慢。

预计算或缓存

  • 静态数据可提前算好页码结果,放入 Redis 或 ES,彻底避开 MySQL。
  • 动态数据可用异步任务把每页首条主键写入缓存,查询时直接 > 条件。

为什么深分页不建议用 limit offset,size

SELECT * FROM t_order LIMIT 4500000, 10;
  • MySQL 仍需扫描450万行然后扔掉,再取 10 行,耗时随 offset 线性增长。
  • 高并发下容易造成 CPU、IO、内存暴涨,甚至 OOM。

一句话总结:“深分页不用 OFFSET,用条件(where)定位起点” 是所有优化手段的核心。

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

相关文章

  • MySQL 如何查询 JSON 数组是否包含特定的值

    MySQL 如何查询 JSON 数组是否包含特定的值

    本文给大家介绍MySQL 如何查询 JSON 数组是否包含特定的值,假设定义了一张表 School,其中字段 stages 为 JSON 类型,本文通过实例代码给大家详细讲解,感兴趣的朋友一起看看吧
    2023-11-11
  • MySQL的存储过程全面解析

    MySQL的存储过程全面解析

    MySQL的存储过程是一组为了完成特定功能而预先编译的SQL语句集,它们存储在数据库中,可以通过一个简单的名字来调用执行,本文给大家介绍MySQL的存储过程基本语法知识,感兴趣的朋友一起看看吧
    2025-09-09
  • 详解MySQL中的基本表与视图

    详解MySQL中的基本表与视图

    Mysql是一种常用的关系型数据库管理系统,其中的基本表和视图是数据库中存储和操作数据的两种重要方式,本文将介绍什么是基本表和视图,并探讨为何要使用视图以及视图的优缺点,最后,将给出在Mysql中创建视图的方法,需要的朋友可以参考下
    2023-09-09
  • MySql版本问题sql_mode=only_full_group_by的完美解决方案

    MySql版本问题sql_mode=only_full_group_by的完美解决方案

    这篇文章主要介绍了MySql版本问题sql_mode=only_full_group_by的完美解决方案,需要的朋友可以参考下
    2017-07-07
  • MySQL 5.6 中的 TIMESTAMP 和 explicit_defaults_for_timestamp 参数

    MySQL 5.6 中的 TIMESTAMP 和 explicit_defaults_for_timestamp 参数

    这篇文章主要介绍了MySQL 5.6 中的 TIMESTAMP 和 explicit_defaults_for_timestamp 参数,需要的朋友可以参考下
    2015-08-08
  • centos7环境下二进制安装包安装 mysql5.6的方法详解

    centos7环境下二进制安装包安装 mysql5.6的方法详解

    这篇文章主要介绍了centos7环境下二进制安装包安装 mysql5.6的方法,详细分析了centos7环境下使用二进制安装包安装 mysql5.6的具体步骤、相关命令、配置方法及操作注意事项,需要的朋友可以参考下
    2020-02-02
  • Mysql 8.0.18 hash join测试(推荐)

    Mysql 8.0.18 hash join测试(推荐)

    这篇文章给大家介绍Mysql 8.0.18 hash join测试的相关知识,本文通过实例代码讲解,非常不错,具有一定的参考借鉴价值,需要的朋友参考下吧
    2019-10-10
  • MySQL 生成随机数字、字符串、日期、验证码及 UUID的方法

    MySQL 生成随机数字、字符串、日期、验证码及 UUID的方法

    这篇文章主要介绍了MySQL 生成随机数字、字符串、日期、验证码及 UUID的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-02-02
  • MySQL误操作后快速恢复数据的方法

    MySQL误操作后快速恢复数据的方法

    这篇文章主要介绍了MySQL误操作后快速恢复数据的方法,需要的朋友可以参考下
    2016-12-12
  • 通过DML更新MySQL数据库数据的示例代码

    通过DML更新MySQL数据库数据的示例代码

    这篇文章主要给大家介绍了如何通过DML更新MySQL数据库的数据,通过DML来对数据库种地表的数据记录进行增删改查操作,文中给大家了详细的代码示例供大家参考,具有一定的参考价值,需要的朋友可以参考下
    2024-01-01

最新评论