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

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

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


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(结果): 既能满足业务需求,也能保证性能稳定性。


总结

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

  • 常见三类方案:

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

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

一句话总结:

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

相关推荐
野犬寒鸦1 天前
从零起步学习并发编程 || 第六章:ReentrantLock与synchronized 的辨析及运用
java·服务器·数据库·后端·学习·算法
saber_andlibert1 天前
TCMalloc底层实现
java·前端·网络
逍遥德1 天前
如何学编程之01.理论篇.如何通过阅读代码来提高自己的编程能力?
前端·后端·程序人生·重构·软件构建·代码规范
冻感糕人~1 天前
【珍藏必备】ReAct框架实战指南:从零开始构建AI智能体,让大模型学会思考与行动
java·前端·人工智能·react.js·大模型·就业·大模型学习
程序员agions1 天前
2026年,“配置工程师“终于死绝了
前端·程序人生
alice--小文子1 天前
cursor-mcp工具使用
java·服务器·前端
晚霞的不甘1 天前
揭秘 CANN 内存管理:如何让大模型在小设备上“轻装上阵”?
前端·数据库·经验分享·flutter·3d
MX_93591 天前
Spring的bean工厂后处理器和Bean后处理器
java·后端·spring
小迷糊的学习记录1 天前
0.1 + 0.2 不等于 0.3
前端·javascript·面试
梦帮科技1 天前
Node.js配置生成器CLI工具开发实战
前端·人工智能·windows·前端框架·node.js·json