MySQL深分页问题与优化思路

前言

大家好,这里是程序员阿亮

大家肯定都用limit进行过分页,这个分页实际上在MySQL之中是一个很笨拙的过程!很容易造成深分页问题!

一、limit深分页问题

假设你有一条这样的 SQL 语句:

sql 复制代码
SELECT * FROM orders ORDER BY create_time LIMIT 1000000, 10;

你主观上是不是认为MySQL 会直接跳到第 100 万行,然后拿出 10 条数据。但事实并非如此。

我们的MySQL会很笨拙地:

大量扫描: MySQL 必须从索引树上按顺序扫描获取 1,000,010(100万零10)条记录。

如果order by的字段是二级索引就会需要大量回表,如果没有,通过filesort也需要大量的回表查询,将100万数据放到sortbuffer里面或者临时文件进行排序在获取最后的10条!

查出这 100万零10 条完整的记录后,MySQL 会丢弃前 100 万条,只将最后的 10 条返回给你。

绝大部分的磁盘 I/O 和 CPU 算力都浪费在了那 100 万条最终要被丢弃的数据上,尤其是"回表"操作带来的大量随机磁盘读取,直接拖垮了性能。

二、优化思路

1.游标分页 / 标签分页(Seek Method)

适用场景: 移动端下拉刷新、瀑布流、或者不需要"跳页"(如直接跳转到第 100 页)的场景。

这是性能最好的分页方式。它的核心思想是:记住上一页最后一条数据的特征(通常是连续的自增 ID 或时间戳),作为下一页的查询条件。

比如说:

sql 复制代码
SELECT * FROM orders ORDER BY id LIMIT 1000000, 10;

优化后:

sql 复制代码
SELECT * FROM orders WHERE id > 1000050 ORDER BY id LIMIT 10;

这样就可以避免我们先获取前100万条数据后丢弃,直接通过索引去获取数据了!

2.子查询、延迟查询优化

适用场景: 必须保留"页码跳转"功能(比如 PC 端的传统分页组件)。

核心思想是:利用"覆盖索引"(Covering Index)极大地减少回表的开销。 我们先通过索引只查出需要的 ID,然后再用这些 ID 去关联原表获取完整数据。

优化前:

sql 复制代码
SELECT * FROM orders ORDER BY create_time LIMIT 1000000, 10;

优化后:

sql 复制代码
SELECT t1.* FROM orders t1
INNER JOIN (
    -- 这里的子查询只查主键 id,如果 create_time 有索引,就能完美命中覆盖索引,无需回表
    SELECT id FROM orders ORDER BY create_time LIMIT 1000000, 10
) t2 ON t1.id = t2.id;

通过这种方式,我们可以先在where条件建立联合索引,通过这个联合索引获取合适的ids,然后再去主键索引获取需要的10条数据,相对来说数据的开销就要小很多,因为在没有子查询的时候,我们的SQL需要获取所有的100万条数据,取出完整的行数据,然后在取最后10条

而我们的子查询则可以先获取符合条件的ids,通过我们的二级索引

然后再通过二级索引去主键索引获取数据,避免了对100万条数据的整行数据扫描。

  • 优点: 子查询中因为只查 id,避免了前 100 万条记录的回表操作,都在内存/索引中完成,性能提升非常明显。然后主查询只需要拿这 10 个 ID 回表查具体数据即可。

  • 缺点: 随着 offset 变得极其庞大(比如千万级别),子查询扫描索引的开销依然不小,只是缓解了痛点。


三、总结

实际上我们业务中使用子查询已经可以将数据在很大程度上进行性能优化了,通过减少数据量与IO来提高我们的性能,也可以通过瀑布分页来达到更高的性能需求,但是这种情况下也就不能满足跳页。

相关推荐
伯明翰java2 小时前
数据库的操作
数据库
知识分享小能手6 小时前
PostgreSQL 入门学习教程,从入门到精通,PostgreSQL 16 语法知识点与案例详解(1)
数据库·学习·postgresql
康康的AI博客6 小时前
智能情感分析与品牌策略优化:如何通过AI洞察提升企业市场响应力
大数据·数据库·人工智能
Anastasiozzzz6 小时前
阿亮随手记:MySQL移除查询缓存、子查询优化深分页、自增主键溢出、索引失效
数据库·mysql·缓存
ppp今天又没打瓦6 小时前
围达梦数据库批量插入更新性能实测:普通表、一级分区与二级分区的对决
数据库
@insist1237 小时前
软考-数据库系统工程师-计算机体系结构与流水线核心考点解析
数据库·软考·数据系统工程师
可观测性用观测云7 小时前
KES(KingbaseES)数据库监控最佳实践
数据库
新缸中之脑7 小时前
在Reddit上探索未满足的需求
数据库·oracle
安当加密8 小时前
用 SMS 凭据管理系统替代 HashiCorp Vault:中小企业的轻量级 Secrets 管理实践
服务器·数据库·安全·阿里云