【MySQL-索引调优】10:常见的分页优化处理

1-游标/书签分页

sql 复制代码
-- 首次查询
SELECT * FROM orders ORDER BY create_time LIMIT 10;
-- 记录最后一条的 create_time = '2024-01-15 10:30:00'

-- 下一页(瞬间定位,与页码无关)
SELECT * FROM orders 
WHERE create_time > '2024-01-15 10:30:00' 
ORDER BY create_time LIMIT 10;

与传统分页的区别:

传统分页 游标分页
LIMIT offset, size WHERE 游标字段 > 上次值 LIMIT size
依赖偏移量(第几页) 依赖锚点(从哪条开始)
页码越深越慢 性能恒定,与深度无关

适用场景:

场景 方案 原因
常规后台(< 1000 页) LIMIT offset, size + 索引 需要支持跳页,数据量可控
大数据后台(> 10w 页) 强制筛选条件 + 限制页码 避免深分页性能灾难
实时性要求低(如报表) 游标分页 + 异步导出 全量导出场景

具体使用:

sql 复制代码
-- 复合索引
INDEX idx_create_time_id (create_time, id)  
-- 首次查询(无游标)
SELECT * FROM orders 
ORDER BY create_time, id 
LIMIT 10;

-- 返回最后一条:create_time='2024-01-15 10:30:00', id=12345

-- 下一页(有游标)
SELECT * FROM orders 
#当 create_time 可能重复时,必须加唯一字段(如 id)确保稳定排序
WHERE (create_time > '2024-01-15 10:30:00') 
   OR (create_time = '2024-01-15 10:30:00' AND id > 12345)
ORDER BY create_time, id 
LIMIT 10;

游标的优势在于深分页时保持恒定性能

2-覆盖索引

索引中已经包含查询所需的全部字段,查询可以直接从索引返回结果,不需要回表

3-延迟关联

先用索引快速定位需要的主键,再用这些主键去表里取完整数据

sql 复制代码
# create_time索引
INDEX idx_create_time (create_time)
# 第一步:只在索引上分页,拿到主键集合
SELECT id
FROM orders
ORDER BY create_time
LIMIT 10000,10;
# 第二步:用这些主键去表里取完整行
SELECT *
FROM orders
WHERE id IN ( ...10个id... )
ORDER BY create_time;
# 只回表 10 次,而不是在分页过程中回表
相关推荐
God__is__a__girl1 小时前
Oracle驱动版本引发ORA-01461批量插入异常排查与解决
数据库·oracle
少年攻城狮2 小时前
Oracle系列---【两个环境,表结构一致,数据量一致,索引也一致,为什么同样的sql执行时间却不一致?】
数据库·sql·oracle
l1t2 小时前
解决用docker安装umbra数据库遇到的FATAL:Operation not permitted错误
数据库·docker·容器
2401_894241922 小时前
机器学习与人工智能
jvm·数据库·python
光影少年2 小时前
如何进行前端性能优化?
前端·性能优化
GentleDevin2 小时前
Redis服务常用命令
数据库·oracle
難釋懷2 小时前
Redis分片集群手动故障转移
数据库·redis·缓存
无名-CODING2 小时前
从零开始!Vue3+SpringBoot前后端分离项目Docker部署实战(上):环境搭建与数据库容器化
数据库·spring boot·docker
Bdygsl2 小时前
MySQL(2)—— CRUD
数据库·mysql