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

分库分表-分页排序查询

优质博文:IT-BLOG-CN

背景:我们系统上云后,数据根据用户UDL部分数据在国内,部分数据存储在海外,因此需要考虑分库查询的分页排序问题

一、分库后带来的问题

需求根据订单创单时间进行排序分页查询,在单表中的查询SQL如下(省略部分查询内容):每页获取10条记录

select orderId, orderStatus from t_order order by create_time asc limit 20, 10

我们做了分库之后,如果需要完成上述的需求,需要在两个表中直接执行如下两条SQLoffset都需要从0开始,否则数据就不正确了。我这里为了区分,表的名字后面带上对应的环境,实际生产sql是一样的,只是查询的库不同而已。

select * from t_order_sha order by create_time asc limit 0,30;select * from t_order_fra order by create_time asc limit 0,30;

如上所示:我们需要将前3页的数据全部查出来,然后在内存中重新排序,最后从中取出第3页的数据,也称为“全局查询法”。

该方案存在的问题: 随着页码的增加,每个节点返回的数据会增多,性能也随着下降。同时,服务层需要进行二次排序,增加了服务层的计算量,如果数据过大,对内存和cpu的要求也非常高。

不过这种方案也有很多优化方案,Sharding-JDBC中就对此方案做出优化,采用的是流式处理和归并排序避免内存的过量占用。

二、禁止跳页查询法

我们部分系统(航班列表页)是通过点击“更多”按钮展示下一页的数据(只提供了查询下一页的功能),此时页面上展示的是前n页的数据集。

上述的功能在分库分页查询的情况下,可以极大的降低业务的复杂度,因为当查询第二页数据的时候,可以将上一页的最大值最为查询条件,此时的SQL可以改写为:

select * from t_order_sha where create_time>1726671336 order by time asc limit 10;select * from t_order_fra where create_time>1726671336 order by time asc limit 10;

查询到数据后需要在内存中进行重新排序,但相对于“全局查询”数据量已经减少了很多,页码越大性能提升越明显。此方案的缺点也非常明显:不能跳页查询,只能一页一页查询。

三、二分查找法

二分查找法既能满足性能要求,也能满足业务要求,不过相对前面两种方案理解起来比较困难。

我们还是以上述的查询语句为例(这里为了演示方便,修改为查询第二页,每页返回5条数据):

select orderId, orderStatus from t_order order by create_time asc limit 5, 5;

【1】SQL改写: 原先的SQLoffset=5,称之为全局offset,这里由于是拆分成了两张表,因此改写后的offset=全局offset/2=5/2=2

核心思想:第一页的5数据肯定包含在t_order_shat_order_fra表中的二分后的0-2之中

最终的落到每张表的SQL如下:

select * from t_order_sha order by create_time asc limit 2,5;select * from t_order_fra order by create_time asc limit 2,5;

红色部分表示查询结果

t_order_shat_order_fra
0000000000100000000002
0000000000300000000008
0000000000400000000009
0000000000500000000010
0000000000600000000011
0000000000700000000012
0000000001300000000014

【2】返回查询数据中的最小值: t_order_sha = 00000000003 (这个过程只需要比较各个分库的第一条数据,时间复杂度很低)

【3】查询二次改写: 第二次查询使用beteween语句,起点是第二部返回的最小值,终点是每个表第一次查询后的最大值。

t_order_sha 这张表,第一次查询的最大值00000000013,则SQL改写后:

select * from t_order_1 where time between 00000000004 and 00000000013 order by time asc;

t_order_fra 这张表,第一次查询的最大值00000000014,则SQL改写后:

select * from t_order_1 where time between 00000000004 and 00000000014 order by time asc;

红色部分为第次的查询结果

t_order_shat_order_fra
0000000000100000000002
0000000000300000000008
0000000000400000000009
0000000000500000000010
0000000000600000000011
0000000000700000000012
0000000001300000000014

在每个结果集中虚拟一个time_min记录,找到time_min在全局的offset

下图蓝色部分为虚拟的time_min,红色部分为第2步的查询结果集。

t_order_shat_order_fra
0000000000100000000002
0000000000300000000004
0000000000400000000008
0000000000500000000009
0000000000600000000010
0000000000700000000011
0000000001300000000012
00000000014

t_order_sha中的第一条数据就是time_min,则offset=3
t_order_fra中的第一条数据为00000000008,这里的offset2,则向上推移一个找到了虚拟的time_min,则offset=1

那么此时的time_min的全局offset=1+3=4

【5】查找最终结果: 找到了time_min的最终全局offset=4之后,再根据第2步获取的两个结果集在内存中重新排序。

[00000000004,00000000005,00000000006,00000000007,00000000008,00000000009,00000000010,00000000011,00000000012,00000000013,000000000104]

现在time_min也就是00000000004offset=4,那么原先的SQLselect * from t_order order by time asc limit 5,5;,此时可以发现SQL中的总偏移量和最小值的偏移量的差值5-4=1,因此需要对排序后的结果集向后推移一位取值。同时因为最小值也包含在集合中的,无论前面的差值是多少,这里都需要将最小值踢出去,所以也需要再向后移一位。根据SQL5条数据,就能够得到如下结果:

00000000006,00000000007,00000000008,00000000009,00000000010

这种方案的优点:可以精确的返回业务所需数据,每次返回的数据量都非常小,不会随着翻页增加数据的返回量。
缺点也是很明显:需要进行两次查询。

相关文章:

分库分表-分页排序查询

优质博文:IT-BLOG-CN 背景:我们系统上云后,数据根据用户UDL部分数据在国内,部分数据存储在海外,因此需要考虑分库查询的分页排序问题 一、分库后带来的问题 需求根据订单创单时间进行排序分页查询,在单表…...

【openwrt-21.02】openwrt PPTP Passthrough 不生效问题解决方案

Openwrt版本 NAME="OpenWrt" VERSION="21.02-SNAPSHOT" ID="openwrt" ID_LIKE="lede openwrt" PRETTY_NAME="OpenWrt 21.02-SNAPSHOT" VERSION_ID="21.02-snapshot" HOME_URL="https://openwrt.org/" …...

【编程基础知识】Mysql的各个索引数据结构及其适用场景

一、引言 在数据库的世界中,索引是提升查询速度的超级英雄。就像图书馔的目录帮助我们快速找到书籍一样,MySQL中的索引加速了数据检索的过程。本文将带你深入了解MySQL索引的多种数据结构、它们的适用场景以及如何巧妙地使用它们来优化性能。 二、索引…...

解决IDEA出现:java: 程序包javax.servlet不存在的问题

问题截图: 解决如下: 1. 点击文件——>项目结构 2. 点击库——>点击——>点击java 3. 找到Tomcat的文件夹,找到lib文件夹中的servlet-api.jar,点击确定 4. 选择要添加的模块 5. 点击应用——>确定...

Comfyui控制人物骨骼,细节也能完美调整!

前言 本文涉及的工作流和插件,需要的朋友请扫描免费获取哦~ 在我们利用Comfyui生成图像的工作中,是否常常因为人物的动作无法得到精确的控制而感到苦恼,生成出来的图片常常达不到自己心中满意的效果。 今天给大家分享的这个工作流&#xff…...

mysql学习教程,从入门到精通,SQL LEFT JOIN 语句(23)

1、SQL LEFT JOIN 语句 在SQL中,LEFT JOIN(也称为左连接)是一种将左表(LEFT JOIN左侧的表)的所有记录与右表(LEFT JOIN右侧的表)中匹配的记录结合起来的查询方式。如果左表中的记录在右表中没有…...

VSCode远程切换Python虚拟环境

VSCode远程切换Python虚拟环境 引言 在现代开发环境中,使用虚拟环境来管理项目依赖是一种普遍的做法。它不仅可以避免不同项目间的依赖冲突,还能让开发者更好地控制和隔离各个项目的环境。Visual Studio Code(VSCode)是一款广受…...

【CSS in Depth 2 精译_038】6.2 CSS 定位技术之:绝对定位

当前内容所在位置(可进入专栏查看其他译好的章节内容) 第一章 层叠、优先级与继承(已完结)第二章 相对单位(已完结)第三章 文档流与盒模型(已完结)第四章 Flexbox 布局(已…...

828 华为云征文|华为 Flexus 云服务器搭建 SamWaf 开源轻量级网站防火墙

在当今数字化高速发展的时代,网络安全问题日益凸显。为了保障网站的稳定运行和数据安全,我们可以借助华为 Flexus 云服务器搭建 SamWaf 开源轻量级网站防火墙。这不仅是一次技术的挑战,更是为网站筑牢安全防线的重要举措。 一、华为 Flexus …...

基于二自由度汽车模型的汽车质心侧偏角估计

一、质心侧偏角介绍 在车辆坐标系中,质心侧偏角通常定义为质心速度方向与车辆前进方向的夹角。如下图所示,u为车辆前进方向,v为质心速度方向,u和v之间的夹角便是质心侧偏角。 质心侧偏角的作用有如下三点: 1、稳定性…...

前端html+css+js 基础总结

​​​HTML 行级元素 标签分为行级元素与块级元素 行级元素占据区域由其显示内容决定&#xff0c;如span&#xff0c;img(图片)&#xff0c;<a></a>基本格式: <a href"链接" target"_blank"></a>用于跳转到其他网站&#xff0c…...

若依VUE项目安全kind-of postcss vite漏洞扫描和修复

npm install unplugin-auto-import0.16.7 npm install vite3.2.11 升级vite、unplugin-auto-import npm install 报错New major version of npm available! 8.5.5 -> 10.8.3&#xff0c;使用命令npm install --force npm install --force...

C语言实现简单凯撒密码算法

**实验2&#xff1a;传统密码技术 【实验目的】 通过本次实训内容&#xff0c;学习常见的传统密码技术&#xff0c;通过编程实现简单代替密码中的移位密码算法&#xff0c;加深对传统密码技术的了解&#xff0c;为深入学习密码学奠定基础。【技能要求】 分析简单代替密码中的移…...

多态的使用和原理(c++详解)

一、多态的概念 多态顾名思义就是多种形态&#xff0c;它分为编译时的多态&#xff08;静态多态&#xff09;和运行时的多态&#xff08;动态多态&#xff09;&#xff0c;编译时多态&#xff08;静态多态&#xff09;就是函数重载&#xff0c;模板等&#xff0c;通过不同的参数…...

OpenHarmony(鸿蒙南向开发)——小型系统内核(LiteOS-A)【Trace调测】

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ 持续更新中…… 基本概念 Trace调测旨在帮助开发者获取内核的运行流程&#xff0c…...

Lombok 在 IntelliJ IDEA 中的使用步骤

Lombok 是一个非常流行的 Java 库&#xff0c;它通过注解简化 Java 类的开发&#xff0c;特别是在处理 POJO&#xff08;Plain Old Java Objects&#xff09;类时&#xff0c;如生成 getter、setter、toString 等常用方法。Lombok 在减少样板代码&#xff08;boilerplate code&…...

计算机网络 --- Socket 编程

序言 在上一篇文章中&#xff0c;我们介绍了 协议&#xff0c;协议就是一种约定&#xff0c;规范了双方通信需要遵循的规则、格式和流程&#xff0c;以确保信息能够被准确地传递、接收和理解。  在这篇文章中我们将介绍怎么进行跨网络数据传输&#xff0c;在这一过程中相信大家…...

git笔记之在多个分支中复用某个分支提交的更改

git笔记之在多个分支中复用某个分支提交的更改 code review! 文章目录 git笔记之在多个分支中复用某个分支提交的更改1.实现该功能的 Bash 脚本示例2.这个脚本是否可以处理新添加的文件&#xff1f;3.该脚本使用前&#xff0c;应先使用下述脚本重置本地仓库所有分支与远程保持一…...

HTML、CSS

初识web前端 web标准 Web标准也称为网页标准&#xff0c;由一系列的标准组成&#xff0c;大部分由W3C (World Wide Web Consortium&#xff0c;万维网联盟) 负责制定。三个组成部分: HTML: 负责网页的结构(页面元素和内容)。CSS: 负责网页的表现(页面元素的外观、位置等页面样…...

数据文件(0)

一、使用场景 1、字典数据 对于一些数据量不大的配置类数据&#xff0c;放到数据库中占用数据库资源&#xff0c;可以放到代码中维护。比如 &#xff08;1&#xff09;字段少业务单一&#xff1a;做成枚举&#xff1b; &#xff08;2&#xff09;字段多业务复杂&#xff1a…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

基于TurtleBot3在Gazebo地图实现机器人远程控制

1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)

考察一般的三次多项式&#xff0c;以r为参数&#xff1a; p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]&#xff1b; 此多项式的根为&#xff1a; 尽管看起来这个多项式是特殊的&#xff0c;其实一般的三次多项式都是可以通过线性变换化为这个形式…...

git: early EOF

macOS报错&#xff1a; Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...

用鸿蒙HarmonyOS5实现中国象棋小游戏的过程

下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...

大数据治理的常见方式

大数据治理的常见方式 大数据治理是确保数据质量、安全性和可用性的系统性方法&#xff0c;以下是几种常见的治理方式&#xff1a; 1. 数据质量管理 核心方法&#xff1a; 数据校验&#xff1a;建立数据校验规则&#xff08;格式、范围、一致性等&#xff09;数据清洗&…...