前言在实际业务开发中尤其是后台管理系统、数据中台、日志系统、电商订单列表等场景MySQL 单表数据量很容易突破百万、千万甚至达到亿级。此时最常见的分页查询语句sqlSELECT * FROM order ORDER BY id LIMIT 1000000, 20;会出现明显性能问题第一页飞快越往后越慢深度分页直接卡死。很多开发者遇到这种问题第一反应是分库分表但分库分表成本高、改造量大并非最优解。本文从原理出发深度剖析 MySQL 分页慢的根本原因并提供8 种从简单到进阶、从业务无侵入到架构级的分页优化方案每种方案附带原理、适用场景、实战 SQL、优缺点分析覆盖 99% 业务场景帮助你彻底解决大数据量分页性能问题。全文干货满满可直接用于生产环境优化与技术博客输出。一、MySQL 大数据量分页为什么会越来越慢想要优化分页必须先搞清楚慢在哪里。1.1 传统 LIMIT 分页执行流程MySQL 执行LIMIT offset, size的逻辑如下扫描满足条件的所有数据按照ORDER BY字段排序跳过前面offset条数据读取之后的size条数据并返回。也就是说sqlLIMIT 1000000, 20MySQL 并不会直接定位到第 1000001 条数据而是先扫描 1000020 条数据丢弃前 1000000 条只返回最后 20 条。1.2 深度分页性能瓶颈根源超大偏移量导致大量无效 IO偏移量越大需要扫描并丢弃的数据越多磁盘 IO 与内存消耗急剧上升。回表查询随机 IO严重拖慢速度如果查询使用非主键索引排序后需要通过主键回表查询完整数据大量随机 IO 会让性能呈指数级下降。无索引或索引失效导致文件排序filesortORDER BY字段无索引时MySQL 无法使用索引排序只能在内存或磁盘中排序数据量大时直接触发磁盘排序性能极差。SELECT * 导致大量无用数据加载查询不需要的字段会增加网络传输、内存拷贝与磁盘 IO 开销放大分页性能问题。1.3 典型性能对比以 1000 万订单表为例LIMIT 0, 20毫秒级返回LIMIT 100000, 20秒级返回LIMIT 1000000, 20十秒甚至几十秒严重影响接口响应下面进入正文8 种高效分页方案逐一详解。二、八种高效分页优化方案实战可直接落地方案一延迟关联优化法通用首选90% 场景适用1. 核心原理先通过索引查询所需主键 ID再通过主键关联查询完整数据。子查询只查主键完全命中索引避免大量回表与无效数据扫描大幅减少 IO。2. 适用场景单表千万级数据分页后台管理系统、列表查询不想改动业务逻辑仅优化 SQL支持跳页、页码分页3. 优化前 SQLsqlSELECT * FROM order ORDER BY id LIMIT 1000000, 20;4. 优化后 SQLsqlSELECT t1.* FROM order t1 INNER JOIN ( SELECT id FROM order ORDER BY id LIMIT 1000000, 20 ) t2 ON t1.id t2.id ORDER BY t1.id;5. 性能提升原理子查询只扫描索引列不加载整行数据减少大量随机 IO 与回表操作外层通过主键查询速度极快6. 优缺点优点业务无侵入、无需改前端、支持传统页码分页、性能提升 10~100 倍缺点依然存在偏移量问题超亿级数据深度分页仍有压力方案二主键定位分页法无限滚动最优方案性能极致1. 核心原理抛弃offset偏移量记录上一页最后一条数据的主键 ID下一页直接使用WHERE id 上一页最大ID定位数据。MySQL 直接通过主键索引定位起始位置不再扫描前面所有数据。2. 适用场景APP 端下拉无限加载小程序列表、信息流不需要跳页只需要上拉 / 下拉数据连续有序3. 实战 SQL第一页sqlSELECT id, order_no, user_id, create_time FROM order ORDER BY id LIMIT 20;假设最后一条 id 1000000第二页sqlSELECT id, order_no, user_id, create_time FROM order WHERE id 1000000 ORDER BY id LIMIT 20;4. 性能特点无论翻到第几页查询时间几乎一致均为毫秒级。5. 注意事项主键必须自增、有序、不重复不支持直接跳转到任意页码逻辑删除数据is_deleted不影响连续性6. 优缺点优点性能极致、无偏移瓶颈、实现简单缺点不支持传统页码跳页前端需配合改造方案三覆盖索引优化法零 SQL 改造仅加索引提速1. 核心原理让查询所需字段、排序字段全部包含在索引中形成覆盖索引。MySQL 直接从索引获取数据无需回表避免随机 IO。2. 适用场景固定字段列表查询不想修改 SQL 语句排序字段明确中小型分页优化3. 实战示例查询语句sqlSELECT id, order_no, user_id, create_time FROM order ORDER BY create_time LIMIT 100000, 20;创建覆盖索引sqlCREATE INDEX idx_create_time ON order (create_time, id, order_no, user_id);4. 为什么快索引是有序结构避免 filesort无需回表查询减少大量随机 IO索引体积小加载更快5. 优缺点优点无需改代码、无需改 SQL、见效快缺点索引占用空间增加写入性能略有下降方案四分段范围分页法支持跳页 超大数据量1. 核心原理根据业务字段时间、ID、用户 ID提前划定数据范围缩小扫描区间避免全表扫描。适用于后台系统需要跳页但数据量巨大的场景。2. 适用场景后台管理系统按时间 / 类型分区的数据亿级数据分页支持跳页3. 实战 SQLsqlSELECT * FROM order WHERE create_time 2024-01-01 00:00:00 AND create_time 2024-02-01 00:00:00 ORDER BY id LIMIT 0, 20;下一页sqlSELECT * FROM order WHERE create_time 2024-01-01 00:00:00 AND create_time 2024-02-01 00:00:00 AND id 上一页最大ID ORDER BY id LIMIT 20;4. 优化思路用时间范围过滤 99% 无效数据再配合主键定位实现高效分页可支持页码跳转与总数统计5. 优缺点优点支持跳页、适合超大数据量、性能稳定.缺点需要业务字段支持分段需要估算范围方案五子查询定位法简单高效轻量级替代方案1. 核心原理先通过子查询找到偏移量起始位置的主键 ID再基于该 ID 向后查询。避免大偏移量扫描大量数据。2. 实战 SQLsqlSELECT * FROM order WHERE id ( SELECT id FROM order ORDER BY id LIMIT 1000000, 1 ) ORDER BY id LIMIT 20;3. 适用场景不想写复杂关联快速优化老项目分页数据量千万级内4. 优缺点优点写法简单、性能优于传统 LIMIT缺点子查询在极端场景下优化器可能选择不当方案六冗余分页表法超高并发列表专用1. 核心原理将需要分页的核心数据单独存入一张冗余表只保留关键字段与主键。分页查询只查小表详情再查主表。2. 适用场景首页列表、高并发热点列表不需要查询所有字段对响应速度要求极高3. 实现思路建立order_list冗余表通过定时任务 / 监听 binlog 同步数据分页只查order_list点击详情再通过 id 查询order主表4. 优缺点优点超高并发、查询极快、不影响主库缺点数据一致性需要保证增加维护成本方案七分区表优化法亿级日志 / 历史数据专用1. 核心原理使用 MySQL分区表按时间或 ID 范围将大表拆分为多个物理文件。分页时只扫描对应分区避免全表扫描。2. 实战示例按时间分区sqlCREATE TABLE order ( id BIGINT PRIMARY KEY, order_no VARCHAR(32), create_time DATETIME ) ENGINEInnoDB PARTITION BY RANGE (TO_DAYS(create_time)) ( PARTITION p202401 VALUES LESS THAN (TO_DAYS(2024-02-01)), PARTITION p202402 VALUES LESS THAN (TO_DAYS(2024-03-01)), PARTITION p202403 VALUES LESS THAN (TO_DAYS(2024-04-01)) );3. 优缺点优点物理层面拆分数据深度分页性能提升明显缺点分区设计复杂跨分区查询性能差方案八搜索引擎替代法海量数据终极方案1. 核心原理MySQL 不适合海量数据复杂检索与分页使用 ElasticSearch 专门负责搜索与分页。MySQL 只负责存储与更新。2. 适用场景亿级以上数据多条件组合筛选模糊查询、高亮、排序复杂高并发搜索3. 架构流程数据写入 MySQL通过 Canal / 定时任务同步到 ES前端分页、筛选、排序全部请求 ES通过 ID 回查 MySQL 获取详情4. 优缺点优点支持海量数据、复杂查询、毫秒级响应缺点增加中间件架构复杂度提升维护成本高三、八种方案全面对比与选型指南为方便你在实际业务中快速选择下表从性能、复杂度、业务侵入性、适用场景做全面对比表格优化方案性能等级代码改造量支持跳页适用数据量推荐场景延迟关联法⭐⭐⭐⭐极小支持千万级通用后台系统首选主键定位法⭐⭐⭐⭐⭐小不支持千万亿级APP 无限滚动、信息流覆盖索引法⭐⭐⭐无支持百万千万级快速优化、固定列表查询分段范围法⭐⭐⭐⭐中支持亿级后台跳页 大数据量子查询定位法⭐⭐⭐极小支持千万级内老项目快速优化冗余分页表法⭐⭐⭐⭐中支持高并发列表首页、热点列表分区表法⭐⭐⭐⭐中支持亿级历史数据日志、订单历史ES 搜索引擎⭐⭐⭐⭐⭐大支持亿级 复杂检索、超高并发选型建议普通后台管理系统→ 延迟关联法APP / 小程序信息流→ 主键定位法快速优化老项目→ 覆盖索引 子查询定位亿级后台跳页→ 分段范围法高并发首页→ 冗余分页表日志 / 历史数据→ 分区表海量复杂搜索→ ElasticSearch四、分页优化通用军规必须遵守严禁无索引排序ORDER BY字段必须建索引否则必触发 filesort。** 严禁 SELECT ***只查业务需要字段减少 IO 与内存消耗。严禁超大偏移量直接分页LIMIT 1000000,20 这种写法必须优化。尽量使用主键排序主键索引是聚簇索引排序性能最高。避免在分页语句中使用复杂函数、隐式转换容易导致索引失效。统计总数 COUNT () 单独优化大数据量不要使用COUNT(*)可缓存总数或使用 ES 统计。禁止在事务中执行慢分页查询容易导致锁等待、事务超时。深度分页优先使用范围查询而非偏移量五、真实生产环境优化案例某电商订单系统订单表 8000 万数据传统分页 LIMIT 1000000,20 查询耗时 14 秒。优化方案延迟关联 主键定位 覆盖索引。优化后同一页查询耗时从 14s 降至 30ms 以内接口性能提升近 500 倍。另一日志系统3 亿数据使用 MySQL 分区表 分段范围分页查询耗时从秒级降至毫秒级。六、总结MySQL 大数据量分页慢本质不是 LIMIT 本身慢而是大偏移量导致大量无效扫描 回表随机 IO 无索引排序。本文提供的 8 种方案从简单 SQL 优化到架构级改造覆盖所有业务场景低成本快速优化延迟关联、子查询、覆盖索引高性能无偏移分页主键定位法亿级数据跳页分段范围、分区表超高并发与复杂检索冗余表、ES实际开发中优先使用延迟关联法与主键定位法基本可以解决 95% 以上的分页性能问题。只有当数据量达到亿级且查询复杂时才考虑引入 ES 或分库分表。掌握这 8 种方案无论面试还是生产优化都能从容应对彻底告别 MySQL 深度分页性能焦虑。点赞收藏关注继续分享mysql技巧。