SELECT id, title FROM articles
WHERE id > 9021000
ORDER BY id LIMIT 20;

后台导出按 limit 20 offset 900000 翻页,每页耗时 6 秒,越往后越慢。Handler_read_next 每次都是九十万量级。这类现象通常不是突然出现的,往前翻半天日志能看到苗头。

追下去是这么回事:offset 不是真的跳过,是先把前面九十多万行读出来再丢掉,代价和页号成正比。后面几页还要回表取整行,随机 IO 把差距再放大一遍。

「深分页 offset」改完先别急着全量,挑一台机器放半天,真有问题这段时间就能看出来。监控和日志的时间要对上,时区不一致会多绕很大一圈。

临时改动用注释写上日期和原因,过两周自己都记不清为什么这么写。动手前把原文件复制一份带时间戳,出问题立刻换回去,比现场分析快得多。

处理上按这个顺序:把 offset 翻页改成按主键游标 where id 大于上一页最后一个 id;排序键不唯一时用 create_time 加 id 的组合游标 避免漏行;确实要跳页就在前端限制最大页数 别开放无限翻页;改完对比两次请求的 Handler_read_next。

确认没问题再收工,最后一页和第一页耗时接近 Handler_read_next 稳定在 20 上下 不再随页码增长。

作者 9823189