【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 次,而不是在分页过程中回表
相关推荐
数据工匠老o22 分钟前
一张 5 亿行的表按月分区后,清理历史数据从几小时变成了几秒
数据库·sql
蒸鱼Yuzheng44 分钟前
Shader 指令成本回归:离线编译、设备权重与误报控制
ci/cd·性能优化·gpu·shader·vulkan
hwscom44 分钟前
几分钟开防护,SQL和XSS注入全被护卫神挡住
数据库·sql·xss
石小千1 小时前
Redis开启ACL认证
数据库·redis·缓存
Dxy12393102161 小时前
MySQL JSON 生成列索引原理、实战与坑点
mysql·adb·json
东风微鸣1 小时前
把 Tailscale 接进 Prometheus 监控
java·数据库·prometheus
wno7041 小时前
MYSQL 常用合并函数
android·数据库·mysql
东风微鸣1 小时前
一次断电引发的血案:Ubuntu 26.04 升级中断后的完整救援实录
数据库·ubuntu·postgresql
大侠归来1 小时前
事务能回滚吗?Pipeline 算事务吗?
java·数据库·oracle
临床数据科学和人工智能兴趣组2 小时前
字符串转换为句子风格
大数据·数据库·人工智能·r语言·r语言-4.2.1