找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1887

积分

0

好友

248

主题
发表于 6 天前 | 查看: 19| 回复: 0

分页查询复杂度示意图

在项目初期的列表页中,分页查询通常非常简单:分页、查数据、返回结果,一切都很顺畅。page 方法看起来像是一个已经帮你处理好所有事情的“黑盒”能力。

但只要业务需求向前推进一步——加入排序、增加筛选条件或组合多种查询条件,情况就开始变得复杂起来。这种变化往往不是突然爆发的,而是随着时间推移慢慢显现。

1. 初期:分页查询几乎没有负担

项目初期的分页查询,代码通常如下所示:

page(new Page<>(pageNo, pageSize), wrapper);

这个阶段的特点是:

  • 查询条件较少
  • 排序规则固定
  • 数据量可控

分页的职责非常单一:限制返回数量 + 控制页码跳转。此时,page 方法几乎不会引发任何性能或稳定性问题。

2. 加入排序:打破分页的“稳定性”

第一个常见的变化是支持前端动态排序,例如:

  • 按创建时间倒序排列
  • 按某个数值字段(如价格、评分)排序
  • 支持升序与降序的切换

代码中开始出现这样的语句:

wrapper.orderByDesc("create_time");

这时,一个很容易被忽略的问题浮出水面:分页的准确性高度依赖排序的稳定性

如果排序字段具有以下特征:

  • 不是唯一键(存在重复值)
  • 数据更新频繁(值会动态变化)
  • 存在大量相同值(如状态字段)

那么在翻页过程中,很容易出现:

  • 同一条数据出现在相邻的不同页面
  • 翻页时数据“缺失”或“重复”

问题的根源不在于分页本身,而在于排序规则缺乏确定性

3. 增加筛选条件:分页查询开始“变形”

接下来,业务通常会增加各种筛选条件:

  • 状态过滤(如仅显示“已审核”)
  • 类型筛选
  • 时间范围查询
  • 关键词模糊搜索

于是,查询条件包装器(Wrapper)中开始出现大量的条件判断逻辑:

if (status != null) {
    wrapper.eq("status", status);
}
if (keyword != null) {
    wrapper.like("name", keyword);
}

此时,分页的角色已经发生了转变:它不再仅仅是“查询一页数据”,而是在一个动态变化的数据集合中截取其中一段。这会带来两个现实问题:

  1. 查询条件稍有变化,原有页码就可能失效
  2. 前端的翻页逻辑变得难以预测

你会开始观察到一些看似“偶发”的现象:

  • 翻到某一页时突然没有数据
  • 查询条件未变,但数据总数前后不一致
  • 同样的参数,返回的结果却不同

4. 排序与筛选叠加:SQL 复杂度快速上升

当排序和筛选条件同时存在时,生成的分页 SQL 通常会包含:

  • 多条件的 WHERE 子句
  • 多字段的 ORDER BY 子句
  • LIMIT / OFFSET 分页限制

在数据量较小时,这些问题并不明显。但一旦数据量增长,以下问题开始集中出现:

  • 查询响应时间变慢
  • COUNT 查询明显耗时
  • 索引开始“失效”或无法有效利用

分页查询,逐渐成为列表页中最重的一条 SQL

5. COUNT 查询:被低估的性能瓶颈

许多人关注分页查询慢,却忽略了一个关键事实:page 方法实际上执行了两条 SQL 语句。

  • 一条用于查询当前页的数据
  • 另一条用于查询满足条件的总数(COUNT)

当筛选条件复杂时,COUNT 查询往往比数据查询本身还要慢。尤其是在以下场景:

  • 涉及多表 JOIN
  • 条件动态拼接
  • 包含多个模糊搜索

这时你会发现:页面加载很慢,但实际返回的数据量并不多。分页的性能问题,很多时候症结不在“查数据”,而在“算总数”。

6. 业务计算字段排序:问题进一步加剧

在真实业务中,排序字段并不总是数据库中的原始字段。例如:

  • 按业务状态优先级排序(如“进行中”优先于“待处理”)
  • 按自定义权重评分排序
  • 按组合规则(如“评分 × 热度”)排序

这类基于业务计算的排序一旦引入,分页查询的负担会明显加重:

  • SQL 语句可读性下降
  • 数据库索引基本失效
  • 分页结果的稳定性进一步降低

此时的 page,已经很难再被当作一个简单的工具来使用。

7. 后期:分页查询成为系统“脆弱点”

在项目后期,典型的分页查询通常具备以下特征:

  • 条件繁多且动态
  • 排序规则复杂
  • 被多个功能模块复用
  • 修改一处可能影响多个页面

于是,代码库中常见的一种状态是:

  • 功能能正常运行
  • 但无人敢轻易修改
  • 出现问题后往往只能回滚

分页查询,反而成了系统中最“脆弱”的一段业务逻辑。

小结

page 方法本身并没有变复杂,复杂的是围绕它不断叠加的排序规则和筛选条件

当你发现分页查询开始出现:

  • 结果不稳定
  • 性能明显下降
  • 修改和维护风险变高

这往往不是因为分页实现有误,而是因为它承担了超出其原始职责的业务复杂度。理解这一点,许多分页相关的问题在早期就有迹可循。

向下箭头表示性能下降

对于分页查询的优化,需要从索引设计、查询重写、缓存策略等多方面入手。更多关于数据库性能优化和后端架构的深入讨论,欢迎访问云栈社区的技术论坛。

开心卡通角色表示积极解决




上一篇:Lux基础模型上手指南:实现AI自动操控计算机
下一篇:深入剖析MyBatis反射模块:对象实例化、属性访问与元数据获取的底层实现
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-1-10 18:36 , Processed in 0.298144 second(s), 38 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表