mysql查询结果分页执行慢_利用延迟关联优化大数据量分页查询

浅强大大_2086

浅强大大_2086

2026-04-27

632人浏览

原创

OFFSET越大越慢,因MySQL需逐行跳过前N行再取结果;延迟关联通过子查询先取ID再JOIN优化,可减少90%+ I/O,但需确保排序字段加主键防重复。

mysql查询结果分页执行慢_利用延迟关联优化大数据量分页查询

为什么 OFFSET 越大,SELECT * FROM t ORDER BY id LIMIT 10000, 20 就越慢

因为 MySQL 在执行这类查询时,必须先扫描并跳过前 10000 行(哪怕只想要后面 20 行),再取结果。如果 id 上有索引,排序快,但“跳过”动作仍要逐行计数;如果没走索引或涉及回表,更慢。数据量越大、偏移量越大,性能断崖式下跌。

常见错误现象:EXPLAIN 显示 rows 高达几十万甚至百万,Extra 里出现 Using filesort 或 Using temporary;实际执行耗时从毫秒级升到秒级甚至十几秒。

  • 不是数据量大才慢,是 OFFSET 大才慢 —— 即使总数据 100 万行,LIMIT 999990, 10 也会极慢
  • 加 WHERE id > ? 手动模拟分页,只在主键/有序字段上可行,且要求严格单调、无删除空洞
  • 用 ORDER BY create_time 分页时,时间可能重复,导致漏数据或重复翻页

延迟关联(Deferred Join)怎么写:用子查询先捞 ID,再关联原表

核心思路是把“找第 N 页的 ID”和“查这些 ID 对应的完整字段”拆成两步。第一步只走索引,极快;第二步用主键等值 JOIN,也快。

假设表 t 主键为 id,要查第 5001 页(每页 20 条):

SELECT t.* FROM t INNER JOIN (
  SELECT id FROM t ORDER BY id LIMIT 100000, 20
) AS tmp ON t.id = tmp.id;

对比原始写法:SELECT * FROM t ORDER BY id LIMIT 100000, 20,这个优化能减少 90%+ 的 I/O 和 CPU 消耗(尤其当 t 表有宽字段或 TEXT/BLOB 时)。

  • 子查询 SELECT id ... 只读索引,不回表,rows 就是 LIMIT 数(20),不是 100020
  • 外层 JOIN 必须用主键或唯一索引字段,否则无法保证高效匹配
  • 如果排序字段不是主键(比如 ORDER BY status, id),子查询需包含所有排序字段,且外层 WHERE 要补全等值条件,否则可能丢失排序稳定性

MySQL 8.0+ 的窗口函数替代方案:ROW_NUMBER() 不适合分页

ROW_NUMBER() OVER (ORDER BY id) 看起来直观,但实际执行会强制对全表排序并编号,内存/磁盘开销巨大,比 LIMIT OFFSET 更慢,不能用于线上分页场景。

MySQL8 CRM Schema Design Expert
MySQL8 CRM Schema Design Expert

面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。

下载

正确做法仍是延迟关联;窗口函数更适合“取 TOP N”或“按组排名”,而非分页。

  • SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY id) rn FROM t) t1 WHERE rn BETWEEN 100001 AND 100020 —— 这个语句逻辑对,但性能灾难
  • MySQL 8.0 的 OFFSET 本身没优化,只是语法支持更全,底层执行策略未变
  • 如果业务允许,用游标分页(WHERE id > last_seen_id LIMIT 20)比任何基于 OFFSET 的方案都可靠、快

容易被忽略的边界问题:排序字段有重复值怎么办

如果用 ORDER BY create_time,而多行 create_time 相同,MySQL 排序结果不稳定,延迟关联子查询返回的 ID 顺序可能和外层 JOIN 时不一致,导致漏行或重复。

解决方案是在排序字段后追加主键,确保唯一性:

SELECT t.* FROM t INNER JOIN (
  SELECT id FROM t ORDER BY create_time, id LIMIT 100000, 20
) AS tmp ON t.id = tmp.id;
  • 不加 id 的后果:两次执行同一语句,可能拿到不同 20 行,前端翻页“闪退”或“卡住”
  • 即使业务上 create_time 理论不会重复,也要防数据库时钟精度、批量插入等现实因素
  • 不要依赖 ORDER BY create_time DESC, id DESC 后再用 id 游标 —— 方向反了容易错乱,统一用升序 + > 最稳妥

分页慢的本质不是数据多,是 MySQL 不得不“数着走”。延迟关联绕开了数,但前提是排序字段可收敛、关联字段够快。真正上线前,务必用真实数据量 + 真实偏移量跑 EXPLAIN FORMAT=JSON 看 sort_buffer_size 是否溢出、是否用到覆盖索引。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

mysql 大数据

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
大数据分析工具有哪四个
大数据分析工具有哪四个

大数据分析的四个工具分别是rapidminer、Hpcc、Hadoop和Pentaho bi。大数据分析用于从各种来源生成的原始数据中提取有价值的数据。这些数据帮助我们获得有意义的见解、隐藏的模式、未知的相关性、市场趋势等等,具体取决于行业。大数据分析的主要动机是提供有价值的见解,以便为未来做出更好的决策。php中文网为大家带来了大数据分析的相关教程、以及相关文章等内容,供大家免费下载使用。

2023.06.21

5996

5

Java 大数据处理基础(Hadoop 方向)
Java 大数据处理基础(Hadoop 方向)

本专题聚焦 Java 在大数据离线处理场景中的核心应用,系统讲解 Hadoop 生态的基本原理、HDFS 文件系统操作、MapReduce 编程模型、作业优化策略以及常见数据处理流程。通过实际示例(如日志分析、批处理任务),帮助学习者掌握使用 Java 构建高效大数据处理程序的完整方法。

2025.12.08

1269

12

大数据专业学习教程
大数据专业学习教程

本专题整合了大数据专业学习相关教程,阅读专题下面的文章了解更多详细内容。

2026.01.05

243

5

python处理大数据合集
python处理大数据合集

本专题整合了python处理大数据相关教程,阅读专题下面的文章了解更多详细内容。

2026.01.05

526

22

mysql修改数据表名
mysql修改数据表名

MySQL修改数据表:1、首先查看数据库中所有的表,代码为:‘SHOW TABLES;’;2、修改表名,代码为:‘ALTER TABLE 旧表名 RENAME [TO] 新表名;’。php中文网还提供MySQL的相关下载、相关课程等内容,供大家免费下载使用。

2023.06.20

2473

6

MySQL创建存储过程
MySQL创建存储过程

存储程序可以分为存储过程和函数,MySQL中创建存储过程和函数使用的语句分别为CREATE PROCEDURE和CREATE FUNCTION。使用CALL语句调用存储过程智能用输出变量返回值。函数可以从语句外调用(通过引用函数名),也能返回标量值。存储过程也可以调用其他存储过程。php中文网还提供MySQL创建存储过程的相关下载、相关课程等内容,供大家免费下载使用。

2023.06.21

1499

5

mongodb和mysql的区别
mongodb和mysql的区别

mongodb和mysql的区别:1、数据模型;2、查询语言;3、扩展性和性能;4、可靠性。本专题为大家提供mongodb和mysql的区别的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.18

875

5

mysql密码忘了怎么查看
mysql密码忘了怎么查看

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql密码忘了怎么办呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.19

3532

5

mysql创建数据库
mysql创建数据库

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql怎么创建数据库呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.25

6088

4

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL vs MySQL
PostgreSQL vs MySQL

共1课时 | 194人学习