⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 juejin.cn/post/7546324539988639790 「龙在天」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注微信公众号:【芋道源码】有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言都将得到认真回复。甚至不知道如何读源码也可以请教噢。
  4. 新的源码解析文章实时收到通知。每周更新一篇左右。
  5. 认真的源码交流微信群。

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

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

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

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

举个例子:

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

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

2. 三种主流解决方案

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

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

3. 全局查找法的真相

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

原理图

问题

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

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

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

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

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

做法

  • 第 1 页:
SELECT * FROM table ORDER BY id LIMIT size;
  • 第 2 页:
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. 1. 1. 不是所有场景都需要分页方案
  2. 2. 2. 三种主流解决方案
  3. 3. 3. 全局查找法的真相
    1. 3.1. 原理图
    2. 3.2. 问题
  4. 4. 4. 优化:禁止跳页,顺序翻页更香
    1. 4.1. 做法
    2. 4.2. 优点
    3. 4.3. 缺点
  5. 5. 5. 不推荐的方案:二次查询法
  6. 6. 6. 面试怎么答(STAR 法则)
  7. 7. 总结