面试官微笑发问:第100万页怎么查?我差点当场沉默…



大家好,我是小米,31 岁,依旧活跃在互联网一线岗位,继续跟大家分享技术干货。今天我们聊一个经常出现在 MySQL 8.x 面试题 里的问题: "超大分页怎么处理?"

说到分页,可能很多小伙伴第一反应就是 ------ limit offset, size,写起来简单,查小表快得飞起。但一旦数据量上亿,尤其是要查 limit 1000000, 10 这种页码巨大的场景,SQL 立马变成性能杀手。

我先讲个我朋友面试的真实故事。

故事开头:面试里的"灵魂拷问"

前段时间,我朋友阿辉去面一家头部互联网公司,面试官很和气,但抛出的题却直击灵魂:

"假设你们有一张订单表,几千万数据,用户要看第 100 万页,SQL 怎么写?怎么优化?"

阿辉当场懵了,心里想:"分页就分页嘛,加个 limit 不就行?"可话到嘴边又停住,因为他想起自己写过的 limit 1000000, 10 在测试环境跑了半天没结果。

于是,他硬着头皮说:"可以加索引吧......"

面试官笑了笑:"能不能具体点?"

你看,这种题就是面试官的常规武器。能不能答好,直接决定了你是不是只会写 CRUD,还是能做真正的性能优化。

为什么超大分页慢?

我们先回到原理。MySQL 的分页是 "扫描+丢弃" 的过程。比如:

MySQL 会先扫描 1000010 条数据,丢掉前 100 万,再返回 10 条。

换句话说,页码越靠后,浪费的扫描越多,性能呈指数级下降。

这就好比你去排队取快递,快递员一件件往后翻,找到第 100 万个时,你早就下班了。

所以,问题的关键是:如何避免无意义的扫描?

接下来我带大家过一遍面试官想要的几个思路。我会结合场景讲,保证你记得住。

利用索引 + 覆盖条件

最经典的优化就是:不要用 offset,而是利用 索引定位起点

比如订单表有主键 id,我们可以改成:

这样 MySQL 直接跳过前面数据,定位到 id 较大的部分,不需要做大量丢弃。

这就像快递员直接从第 100 万个快递开始翻,而不是从第一个开始数。

不过注意,这个方案要求分页是 基于主键顺序的。如果你要按创建时间排序,那就得在 created_at 上建索引。

延迟关联(或称"子查询 + join")

还有一个套路:先用索引字段做子查询,获取主键,再回表查询其他字段。

这样子查询部分只走索引,返回很快;主查询只查 10 条数据,避免了大范围扫描。

这就好比你先记下第 100 万个快递的编号,再直接去货架拿,不需要傻傻从头找。

覆盖索引 + 边走边翻页

如果分页需要支持"上一页、下一页",我们可以用 基于游标的分页(cursor based pagination) 。举个例子:

这里的 '2023-05-01 10:00:00' 相当于上一页最后一条数据的时间戳。下一次分页就从这里继续查,效率高得多。

这就是很多大厂 API 的默认分页方式:基于游标,不基于 offset

业务层面的优化

面试官常常还会追问一句:

"除了 SQL 优化,业务上能怎么搞?"

这就是考察你能不能 跳出数据库思维

几种思路:

  • 限制最大页数:谁会真的翻到第 100 万页?很多系统干脆只允许翻到 100 页。
  • 搜索+过滤结合:用户如果要找历史订单,可以先选条件缩小范围,再分页。
  • 异步加载 / 下拉刷新:前端做"无限滚动",用户体验好,SQL 压力也小。

这类回答很加分,因为它体现了 技术与业务结合的思维

MySQL 8.x 的新武器

既然是 MySQL 8.x 面试题,别忘了加点 版本特色,面试官会觉得你真用过。

  1. 窗口函数:MySQL 8.x 支持窗口函数,我们可以用 row_number() 给结果集编号,然后取某一段:

虽然性能未必比传统分页快,但写法灵活,而且考察你对新特性的掌握。

  1. CTE(公用表表达式) :在 MySQL 8.x 里可以用 CTE 重写分页逻辑,更清晰,也便于调试。
  2. InnoDB 隐式主键优化:MySQL 8.x 对主键分页性能优化得更好,面试时可以顺带提一句"升级版本能提升性能"。

总结:怎么在面试中答?

到这儿,我们已经盘点了超大分页的优化思路。那面试的时候,怎么说才显得层次分明?

我给你一个参考答法:

  1. 先指出问题本质:MySQL 分页是"扫描+丢弃",大页 offset 性能差。
  2. 再讲 SQL 优化
    1. 用索引替代 offset
    1. 子查询+join(延迟关联)
    1. 游标式分页(基于主键/时间)
  3. 补充业务优化:限制页数、增加条件、下拉刷新。
  4. 顺带提 MySQL 8.x 特性:窗口函数、CTE 等。

这样回答下来,既有深度,又有广度,面试官一定会点头。

番外:真实工作里的选择

最后我想说,很多时候"超大分页"更多是理论题。真实场景下,用户根本翻不到第 100 万页。

所以在实际工作里,我更常用的是 游标分页 + 前端下拉加载,配合 Redis 做热点数据缓存,既能保证体验,又能节省数据库压力。

面试题的意义,不只是考你写 SQL 的能力,而是考你能不能 从底层原理、技术方案、到业务优化,完整地分析问题

END

好了,今天这篇文章就分享到这里。

如果你正准备面试 MySQL 相关岗位,记住:碰到"超大分页"问题,不要慌。把原理、方案、业务结合一说,面试官一定会觉得你是"能落地的工程师",而不是"只会背八股的候选人"。

我是小米,一个喜欢分享技术的31岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号"软件求生",获取更多技术干货!

相关推荐
文心快码BaiduComate4 小时前
文心快码升级至3.5S版本,强化多智能体自协同能力
前端·后端·程序员
breeze_whisper4 小时前
当前端收到一个比梦想还大的数字:BigInt处理指南
前端·面试
小高0074 小时前
性能优化零成本:只加3行代码,FCP从1.8s砍到1.2s
前端·javascript·面试
即兴小索奇4 小时前
Google AI Mode 颠覆传统搜索方式,它是有很大可能的
前端·后端·架构
LucianaiB4 小时前
我用LazyLLM做了一个打工人述职Agent,朋友直呼打工人的福利,太完美了
后端
今禾4 小时前
深入浅出:ES6 Modules 与 CommonJS 的爱恨情仇
前端·javascript·面试
前端小白19954 小时前
面试取经:Vue篇-Vue2响应式原理
前端·vue.js·面试
用户47949283569154 小时前
每天都在用大模型,但是你知道temperature、top_p、top_k这些常见参数是做什么的吗?
人工智能·面试·llm
小蒜学长5 小时前
旅行社旅游管理系统的设计与实现(代码+数据库+LW)
java·数据库·spring boot·后端·旅游