Sunday面试指南

MySQL 深分页为什么越来越慢?游标分页和延迟关联怎么优化?

🧑‍💻 面试官:MySQL 翻到第 5000 页越来越慢,给排序字段加个索引就能解决吗?

🙋‍♂️ 我:应该可以。索引能直接找到这一页的数据。

🧑‍💻 面试官:LIMIT 100000, 20 里的十万条,数据库真的不用经过吗?

🙋‍♂️ 我:那先只查 ID,再回表取这 20 条。

🧑‍💻 面试官:这减少了回表,可偏移扫描还在。要彻底绕开大偏移,你准备怎么改接口?

这道题要分清两笔开销:跳过多少条,以及为多少条读取完整记录。延迟关联减少后者,游标分页才有机会避开前者。

面试速答(60 秒版)

深分页慢,通常是因为数据库要找到有序结果,再跳过前面的很多条,只返回最后一小段。加索引能改善排序和读取,但不会让大 OFFSET 自动消失。

如果页面支持连续翻页,我会优先考虑游标分页:带上上一页最后一条的排序值和唯一 ID,从这个位置继续查。排序字段相同时,ID 负责确定先后。

如果必须跳到任意页,可以先通过覆盖索引查这一页的 ID,再关联主表取详情,减少前面那些记录的回表成本。不过它仍要经过偏移区间。

最后要用真实筛选条件和数据分布看执行计划。分页是否正确、是否需要固定快照,也要和性能一起考虑。

OFFSET 扫描偏移,延迟关联减少回表,游标从已知位置继续

知识点详解:数据库为什么不能直接跳到第 5000 页

先把 OFFSET 理解成“跳过结果”,不是“数组下标”

假设后台按创建时间倒序展示任务,每页 20 条。LIMIT 100000, 20 的意思是:在符合条件的有序结果里,跳过十万条,再拿 20 条。

B+ 树能按键定位,但它通常没有“当前筛选条件下,第十万条就在某个地址”的目录。即使顺着排序索引读,也还需要经过前面的候选记录。没有合适索引时,还可能额外筛选和排序。

所以,面试里不能只说“深分页没有走索引”。已经走索引,也可能因为读过太多条而慢。

游标分页:下一页从上次的位置接着走

例如使用 (created_at, id) 建立索引,并约定两个字段都倒序。下一页的游标必须同时保存时间和 ID:

SELECT id, created_at, title
FROM tasks
WHERE created_at < :last_time
   OR (created_at = :last_time AND id < :last_id)
ORDER BY created_at DESC, id DESC
LIMIT 20;

这里的冒号参数只是示意,由数据库驱动绑定,不要拼接用户输入。第一屏不带游标条件;上一屏最后一条就是下一屏的起点。实际还有租户、状态等过滤时,要重新设计联合索引并核对范围扫描,不能直接套用这个索引。

只保存时间是不够的。同一秒可能有很多任务,缺少唯一的第二排序字段,就无法明确从哪一条接着查。

延迟关联:先找小记录,再取大记录

页面非要展示“跳到第 5000 页”时,游标接口就不完全满足需求。这时可以让子查询先只选 ID 和排序字段,再关联主表取详情。

这样做的关键是:子查询尽量由索引覆盖,只有最终那 20 条才读取完整记录。外层仍应写明确的 ORDER BY,不能依赖子查询顺序自动保留。

它优化的是完整行读取量,不是把十万条偏移变成零。记录越宽、原查询回表越多,收益越可能明显;如果本来就只读覆盖索引,收益就不一定大。

翻页正确性也需要定规则

游标不是数据库快照。连续翻页期间,记录被删除、排序值改变,仍可能影响结果。新记录出现在游标之前,通常不会挤进后续页,但这不等于全程读到同一时刻的数据。

普通信息流可以接受这种变化;审计导出就可能需要固定查询范围或一致性快照。验证时应分别观察扫描条数、回表量、排序和耗时,并加入重复时间、删除和新增的测试。EXPLAIN ANALYZE 会实际执行查询,要在合适的测试环境使用。

本题机制参考:LIMIT 优化、联合索引、EXPLAIN。

面试官继续追问

游标能直接跳第 100 页吗?

通常不能。没有那一页的起点,就不能凭页号直接构造游标。产品要在连续翻页、任意跳页和查询成本之间做取舍。

按 ID 翻页一定正确吗?

只有 ID 顺序符合展示规则时才行。页面按更新时间排序,却用 ID 作为唯一游标,会改变用户看到的顺序。

有索引还慢,先看什么?

先看实际筛选比例、经过的记录量、回表和排序,再判断是不是索引设计问题,不先下结论说数据库没用索引。

面试速记卡

  • OFFSET:跳过结果,不是直接定位数组下标。
  • 游标:保存排序键和唯一键,沿位置继续查。
  • 延迟关联:减少完整行读取,偏移成本仍在。
  • 正确性:固定排序不等于固定快照。
  • 验收:看扫描量、回表、排序和真实耗时。

公司面试真题

真题根据求职者公开面经整理,题意经过概括,非逐字原话或公司官方题库;本文为 Sunday 的独立解析。

  • 京东 · Java后台 · 校招

    大量数据怎样通过主键位置优化分页?(题意整理)

    京东 Java 后台三面凉经 ↗
    原帖编辑于 2019-08-23(历史校招面经)

浏览公司面试真题 →
简历汪永久免费在线制作简历,模板直接套用、导出无水印,永久免费、下载免费,不需要付费解锁任何功能。去写简历