当前位置: 首页 > news >正文

分库分表下如何实现分页查询功能

分库分表(Sharding)环境下的分页查询功能,是工程实践中的一个难点和核心问题。由于数据被分散到不同的库和表中,简单的 LIMIT offset, limit 语句会带来巨大的性能和资源消耗。

以下是分库分表下实现分页查询的几种方案,以及对深度分页的优化:


一、 基本分页实现(通用方案)

对于一般的中间件(如 ShardingSphere、MyCAT 等),它们在处理分页查询时,通常采用“先查后合”的策略:

1. 跨库查询与结果归并

假设要查询第 NNN 页,每页 PPP 条记录(即 LIMIT (N-1)*P, P):

  1. 子查询改写: 中间件会将一个查询请求(如 SELECT * FROM table ORDER BY col LIMIT offset, limit)拆分成对所有分表的子查询。
  2. 子查询执行: 对每个分库分表执行一个扩大了查询范围的子查询:SELECT * FROM table_i ORDER BY col LIMIT 0, offset + limit
    • 关键点: 必须从第 0 条开始查,并取到最终需要的末尾位置,以保证结果集的完整性。
  3. 结果归并: 中间件收集所有分表返回的结果集。
  4. 内存排序与截断: 在内存中对所有结果进行全局排序ORDER BY col),然后根据原始查询的 offsetlimit 进行截断,返回最终所需的数据。

存在的问题(深度分页问题):

offset 值很大时(即查询很靠后的页),子查询需要查询并返回大量数据。中间件在内存中归并和排序的数据量也会非常庞大,极大地消耗网络带宽、CPU 和内存资源,导致系统性能急剧下降。


二、 深度分页的优化方案(推荐)

为了避免在深度分页时拉取和排序海量数据,通常需要调整前端的交互方式或利用索引特性。

1. 利用 ID 排序的优化(推荐使用)

如果你的查询是基于主键(通常是自增 ID)进行排序,可以采用基于游标(Cursor)或上一页最后一条记录 ID 的分页方式,完全避开 offset

查询方式:

SELECT * FROM table
WHERE id > [上页最后一条记录的ID]  -- 游标
ORDER BY id
LIMIT [每页记录数]

实现步骤:

  1. 前端交互改变: 不再提供“跳转到第 100 页”的功能,只提供“下一页”。
  2. 记录游标: 客户端(或服务端)需要记录当前页最后一条记录的 ID(作为下一页查询的起点)。
  3. 子查询优化: 由于 WHERE id > X 是基于索引的查询,数据库可以直接定位到起始位置,大大减少扫描的数据量。

优点: 性能高,避免了跨库归并大量数据的问题。

缺点: 只能应用于按 ID 排序的场景,并且无法实现“跳转页”和“上一页”(如果需要上一页,需要客户端记住前一页的游标)。

2. 利用 Sort Key 优化的方案

如果排序字段(Sort Key)不是 ID,但存在高效的二级索引,也可以借鉴游标法:

查询方式:

SELECT * FROM table
WHERE (sort_key, id) > ('[上页最后一条sort_key]', [上页最后一条ID])
ORDER BY sort_key, id
LIMIT [每页记录数]

这种方法是复合游标法,通过组合 排序键 + 主键 来确保查询的唯一性和连续性,同样能高效利用索引,避免深度的 offset 问题。

3. 两次查询法(适用于非 ID 排序)

当必须支持“跳转页”且排序字段不是 ID 时,可以采用两次查询来优化:

  1. 第一次查询(只查 ID):
    SELECT id FROM table ORDER BY col LIMIT (N-1)*P, P
    
    • 这一步仍然需要跨库归并,但由于只查询了主键 ID,数据量(带宽和内存消耗)大大减少
  2. 第二次查询(查详情):
    SELECT * FROM table WHERE id IN (第一次查询返回的ID列表)
    
    • 根据 ID 列表进行查询,中间件可以根据 ID 路由到对应的分表,直接精确查询并返回数据。

优点: 减少了深分页时传输和归并的数据量,将大范围的全字段查询变为小范围的 ID 查询。

缺点: 引入了两次数据库查询,增加了整体耗时,并且第一次查询的归并排序仍然会消耗一定的 CPU 资源。


总结与建议

场景推荐方案核心优势限制/注意事项
按 ID 排序,只需“下一页”基于 ID 游标(Cursor)性能最高,完全避免深分页问题。无法支持“跳转到任意页”。
按非 ID 字段排序,只需“下一页”基于 Sort Key + ID 游标性能接近 ID 游标,仍可利用索引。复杂排序(多列)场景不适用。
必须支持“跳转到任意页”两次查询法(ID Only Query)在支持跳转的前提下,最大限度节省传输和归并资源。需要两次 DB 往返,且第一次查询仍需跨库归并。
查询页码较浅 (N<10)通用方案(先查后合)实现最简单,代码侵入性最小。不适用于深度分页。
http://www.dtcms.com/a/487706.html

相关文章:

  • 江苏弘盛建设工程集团有限公司网站好看企业官网源码
  • LVDS系列31:Xilinx 7系 ADC LVDS接口参考设计(二)
  • 网站建设是什么?进入百度网首页
  • 【HackTheBox】- Busqueda 靶机学习
  • 127.XIlinx fpga端的pcie(XDMA)与驱动是如何交换数据的
  • 个人网站名称怎么起济南的互联网公司有哪些
  • 在Docker中pip离线安装python的各种包
  • 建设电子商务网站的方法有?网站开发软件三剑客
  • 企业网站管理系统(多语言+多模板)
  • 设计师去哪个网站找工作wordpress linux下载
  • 机器学习入门,无监督学习之K-Means聚类算法完全指南:面向Java开发者的Python实现详解
  • Java 设计模式——代理模式:从静态代理到 Spring AOP 最优实现
  • 网站制作公司属于广告发布者吗自己买服务器搭建网站
  • 有哪些好的建站平台泰兴企业网站建设
  • 阜宁专业做网站广告推广广告
  • 网站建设多少钱需要wordpress商品展示插件
  • c语言位运算 汇编代码分析
  • 民制作网站哪家便宜西安单位网站制作
  • 云南网站开发建设大丰网站建设价格
  • 横山桥网站网站用户群
  • 制作网站培训长沙seo招聘
  • 两阶段不确定性优化:一种用于解决“现在决策、未来见效”问题的强大建模框架。
  • 香港虚拟主机和香港云服务器哪个更安全?
  • 苏州网站建设案例什么是电子商务网站推广
  • 浙江建筑网站南上海网站建设
  • 制作企业网站需要注意的事项wordpress 重装
  • 个人怎么做淘宝客网站seo网站推广的主要目的
  • 输电通道运维助手:重要输电通道沿线气象及覆冰观测系统
  • 镇江网站建设优化排名wordpress 搜索栏目
  • 【论文推导】Tube-based MPC-辅助控制器设计