分库分表下的分页查询,到底怎么搞?

今天聊一个分库分表后的经典难题:分页查询

很多伙伴在面试或者工作里都被问过这个问题,如果没理清楚,容易一头雾水。那我们就用最简单的大白话,把它捋清楚说明白。


1. 不是所有场景都需要分页方案

分页问题只有在 跨库或跨表查询 时才会变复杂。

举个例子:

  • 如果查询条件里总是带 分片键(比如查某个用户ID的数据,或者查某个时间片的数据),那它就是查某一个分片的数据。
  • 这种情况和查单表一模一样,不存在什么分页难题。

👉 所以第一步一定要问:这次查询到底是不是跨分片的?


2. 三种主流解决方案

当我们真的遇到跨分片分页时,常见的有三种办法:

方案 核心思想 优点 缺点
方案1:专用中间件/数据库 (如 Elasticsearch、TiDB) 把分库分表的数据同步到更适合做复杂查询的系统里,由它来处理分页。 性能高,工业界常用方案。 要保证数据同步一致性(MySQL → ES)。
方案2:开源框架 (如 ShardingSphere) 应用还是写"单表SQL",框架在背后把SQL拆开,去各个分片拉数据,再在内存里排序、分页。 对应用几乎零改动,开发体验好。 深度翻页性能差。
方案3:业务妥协 跟产品经理沟通,限制查询范围,不搞跨分片分页。例如只查当前分片,或者提示用户"仅显示部分结果"。 最简单,直接回避问题。 对业务体验可能有影响。

3. 全局查找法的真相

面试中最喜欢问的就是方案2里提到的 全局查找法

⚙️ 原理图

flowchart TD A[客户端 SQL LIMIT offset,size] --> B[各分片执行 LIMIT 0, offset+size] B --> C[汇总数据] C --> D[内存归并排序] D --> E[取 offset 之后的 size 条数据]

⚠️ 问题

  • 正确性没问题,但如果查询第 100,000 页

    • 每个分片要查几十万甚至上百万条数据。
    • 内存里还要排序和裁切。
    • 极容易 OOM(内存溢出),速度慢到怀疑人生。

所以: 👉 全局查找法能用,但翻页浅一点还行,深度翻页会死


4. 优化:禁止跳页,顺序翻页更香

解决深度翻页问题的最佳实践是:基于上一页最大 ID 翻页

✅ 做法

  • 第 1 页:

    sql 复制代码
    SELECT * FROM table ORDER BY id LIMIT size;
  • 第 2 页:

    sql 复制代码
    SELECT * FROM table WHERE id > {上一页最大id} ORDER BY id LIMIT size;

👍 优点

  • 每次只查一页,性能极好。
  • 和 offset 大小无关,不怕深度翻页。

👎 缺点

  • 不能直接跳到第 100 页。
  • 只能一页一页往下翻,像刷微博/抖音一样。

👉 但对大多数场景(信息流、消息列表),完全够用。


5. 不推荐的方案:二次查询法

有些文章会提到"二次查询法"。 它实现复杂,还可能遇到数据分布不均的问题,结果不可靠。

一句话:不推荐使用


6. 面试怎么答(STAR 法则)

如果在面试被问到,可以按 STAR 模型来回答:

  • S(情境): 系统做了分库分表后,跨分片分页成了难题。

  • T(任务): 需要一个能保证全局分页正确性的方案。

  • A(行动)

    1. 首先评估业务,能不能限制查询范围,直接规避问题。
    2. 如果必须实现,首推用 Elasticsearch/TiDB 这类系统。
    3. 如果必须在数据库层面搞,就用 ShardingSphere 的全局查找法,但要说明深度翻页问题。
    4. 针对深度翻页,再提出"基于上一页最大ID"的优化。
  • R(结果): 既能满足业务需求,也能保证性能稳定性。


总结

  • 不是所有分库分表都有分页问题,只有跨分片才需要考虑。

  • 常见三类方案:

    • 中间件/数据库(推荐)
    • 开源框架(方便但有性能坑)
    • 业务妥协(直接回避)
  • 全局查找法能用,但深度翻页会炸。

  • 最佳实践:禁止跳页 + 顺序翻页

一句话总结:

能规避就规避,能交给专用系统就交给专用系统,实在要做就用连续翻页。

相关推荐
想用offer打牌4 小时前
MCP (Model Context Protocol) 技术理解 - 第二篇
后端·aigc·mcp
崔庆才丨静觅5 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60616 小时前
完成前端时间处理的另一块版图
前端·github·web components
KYGALYX6 小时前
服务异步通信
开发语言·后端·微服务·ruby
掘了6 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅6 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅6 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
爬山算法6 小时前
Hibernate(90)如何在故障注入测试中使用Hibernate?
java·后端·hibernate
崔庆才丨静觅7 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment7 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端