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

大批量查询方案简记(Mybatis流式查询)

Mybatis的流式查询

摘要:

介绍使用mybatis流式查询解决大数据量查询问题.

1 业务背景

开发中遇到一个业务,说起来也很无奈:公司用的数据库MySQL,一张表里只保留了一个月的数据,但是数据量竟然高达2000W还要多,然后用户有个需求也很恶心,为了完成这个业务我需要定时任务每一个月跑一次,每次取出上一个月的历史数据,做一次计算,将需求所需要的结果数据保存到另一张表里.那么问题就是我不得不一次性去出这两千多万条数据去计算.

2 分析

既然要从MySQL里面取出这2000多万的数据,那普通的查询肯定不行了,一次性查出来先不说速度慢得问题,光内存估计就会塞爆掉.

分批查询呢? 我之前有写过一篇超300W数据的导入导出的文章,里面介绍了关于使用SQL的批处理加上事务控制以及分批读取的方式解决的,但是这个就不适用于这种业务场景,因为数据量实在太大了

如果分批读取每次查询20万你需要一百多次的查询才能将数据读出来,先不收内存够不够用,时间上就已经浪费很长时间了.

那么分析到这里,我要解决的主要问题其实就两个:

1 内存不要爆掉;

2 时间不能慢,定时任务每个月执行一次,最慢一次处理(查询,数据处理,入库等操作)要保持在15分钟以内)

3 解决方式

这里经过分析和查阅资料我找到了两种解决思路:

1 开线程查询每个线程处理一定量的数据;

2 使用游标查询;

3 使用流式查询;

首先第一种解决方案其实就是普通的分批查询只不过换成了并行方案,我们可以在SQL中使用limit 关键字,然后配合线程池以及CountDownLatch使用,处理结果最终合并每条线成的结果,

​ 优点: 速度比单线程快,如果配合SQL的批处理这样速度不会慢.

​ 缺点: 开销大,对数据库的压力和服务器配置的要求比较高,然后还有就是2000W还要多的数据线程数开多少合适呢?开的少了,效果不明显,开的多了可能会造成MySQL的连接数占满,导致其他查询操作阻塞.

其次第二种解决方案这种其实就是使用fetchSize控制一次读取的条数;这种方式其实也很快

​ 优点:游标查询可以避免内存溢出的问题,主要原因会使用临时空间存储数据。

​ 缺点:1 存在大两IO读取写入操作,在此过程中可能会引起其他业务的写入抖动;

​ 2 磁盘空间会飙升,如果临时空间写入的表数据非常大,可能会导致磁盘空间被打满,正常情况下临时空间的数据会在读取结束或者客户端发器关闭对ResultSet操作的时候被MySQL回收。

​ 3 客户端查询会有很长的等待时间,等待SQL响应;这个时间段内主要是MySQL在准备临时空间数据;

​ 4 当临时空间数据准备完成之后,SQL开始响应,这时IO就可以从写入转变为读取,这时候网络响应也会开始飙升,客户端发生抖动。

最后第三种解决方案 这种流式查询,MySQL会将结果通过输出流进行结果的输出,就是向本地内核的缓存区(socket buffer)输出数据,再通过TCP链路传输将数据传送给JDBC对应的内核缓存区。

​ 优点:速度快,不会内存溢出;

​ 缺点:1 开启流式查询每次只能读取一行数据(注意:所以在我们处理数据的时候要尽量快,这样效率才会更高)

​ 2 如果MySQL 服务一直向JDBC 对应的缓冲区输送数据,如果客户端Socket缓冲区满了就会导致MySQL服务阻塞;

​ 3 相对游标流式查询对数据库的影响时间会更长一些;

​ 4 高度依赖网络,流式查询数据量超大,处理业务复杂的情况下会有更大的概率导致网络阻塞。

​ 5 Java会不断进行GC,数据量较大会可能会抛出GC次数过多的异常,导致业务异常停止。(使用MyBatis操作可能会出现这种情况)

4 Mybatis-plus流式查询代码示例

Service 层 和 Mapper层 代码示例如下

    @Override@Transactional(rollbackFor = Exception.class)public void highFactorCalculation(String startTime, String endTime) {radarFactorDataMapper.selectDataByStream(result -> {// coding ...}, startTime, endTime);// coding ...}
	 /*** 流式获取指定时间内的数据** @param startTime 开始时间* @param endTime   结束时间*/@Options(resultSetType = ResultSetType.FORWARD_ONLY, fetchSize = Integer.MIN_VALUE)@ResultType(Pojo.class)void selectDataByStream(ResultHandler<Pojo> handler, @Param("startTime") String startTime, @Param("endTime") String endTime);

相关文章:

大批量查询方案简记(Mybatis流式查询)

Mybatis的流式查询 摘要: 介绍使用mybatis流式查询解决大数据量查询问题. 1 业务背景 开发中遇到一个业务,说起来也很无奈:公司用的数据库MySQL,一张表里只保留了一个月的数据,但是数据量竟然高达2000W还要多,然后用户有个需求也很恶心,为了完成这个业务我需要定时任务每一个月…...

python - 子类为什么调用父类的方法

菜鸟教程 - 面向对象https://www.runoob.com/python3/python3-class.html为什么写这个呢 &#xff0c;因为很多时候&#xff0c;事情很简单&#xff0c;但我往往记住了使用方式&#xff0c;忘记了使用原因&#xff0c;也因为自己看到super()时&#xff0c;也想问为什么要用supe…...

【JavaScript】数据结构之字典 哈希表

字典 键值对存储的&#xff0c;类似于js的对象&#xff0c;但在js对象中键[key]都是字符串类型或者会转换成字符串类型&#xff0c;因此后声明的键值会覆盖之前声明的值。字典以map表示&#xff0c;map的键不会转换类型。 let map new Map() map.set(a, 1) map.set(b, 2) ma…...

Adobe出现This unlicensed Photoshop app has been disabled

Adobe Acrobat或Photoshop软件突然出现This unlicensed Photoshop app has been disabled 症状 解决方法 删除软件安装目录下的AcroCEF和acrocef_1l两个子文件夹。主要是为了删除AcroCEF.exe。 如果存在复发&#xff0c;则删除xxxxxxx\AdobeGCClient\AdobeGCClient.exe。 不…...

elementui 单元格添加样式的两种方法

方法一 <el-table-column fixed prop"name" label"姓名" width"120"> <<template scope"scope"> <span :class"{red:scope.row.color1,yell:scope.row.color2,green:scope.row.col…...

如何有效管理技术债务:IT项目中的长期隐患

如何有效管理技术债务&#xff1a;IT项目中的长期隐患 在软件开发和IT项目管理中&#xff0c;技术债务&#xff08;Technical Debt&#xff09;是一个经常被忽视却又至关重要的概念。技术债务就像金融债务一样&#xff0c;当我们在项目开发中选择了某些“捷径”来快速交付&…...

2024 “华为杯” 中国研究生数学建模竞赛(D题)深度剖析|大数据驱动的地理综合问题|数学建模完整代码+建模过程全解全析

当大家面临着复杂的数学建模问题时&#xff0c;你是否曾经感到茫然无措&#xff1f;作为2022年美国大学生数学建模比赛的O奖得主&#xff0c;我为大家提供了一套优秀的解题思路&#xff0c;让你轻松应对各种难题&#xff01; CS团队倾注了大量时间和心血&#xff0c;深入挖掘解…...

Linux 清空redis缓存及查询key值

1.登录redis redis-cli -h 127.0.0.1 -p 6379# 如果有密码需要下面这一步 auth 你的密码直接带密码登录 redis-cli -h 127.0.0.1 -p 6379 -a 密码出现ok表示登录成功 2.标题查看所有key keys *3.查看某个key 的值 get keyName4.清空整个Redis服务器的数据 flushall5.查看…...

MySql调优(三)Query SQL优化(2)explain优化

explain执行计划出现以下情况&#xff0c;均需要优化&#xff1a; 一、Using temporary 查询执行过程中出现Using temporary提示&#xff0c;通常意味着MySQL需要创建一个临时表来存储中间结果。这种情况多发生在数据库优化器无法通过现有的索引直接有效地执行查询时&#xf…...

Java【代码 18】处理Word文档里的Excel表格数据(源码分享)

处理Word文档里的Excel表格数据 1.原始数据2.处理程序2.1 识别替换表格表头2.2 处理多余的换行符2.3 处理后的结果 3.总结 1.原始数据 Word 文档里的 Excel 表格数据&#xff0c;以下仅为示例数据&#xff1a; 读取后的字符串数据为&#xff1a; "姓名\r\n身份证号\r\n手…...

21、Tomato

难度 低(个人认为中) 目标 root权限 一个flag 使用VMware启动 kali 192.168.152.56 靶机 192.168.152.66 信息收集 端口信息收集 可以看到有个ftp服务&#xff0c;2211实际是ssh协议端口&#xff0c;80、8888是一个web服务 web测试 80端口显示一个tomato 查看源码给了一些…...

代码随想录 八股文训练营40天总结

参加训练营的话也是给自己一定的约束力&#xff0c;让自己能够定期去对八股文进行一个背诵&#xff0c;虽然说中间有几天放假&#xff0c;没有进行打卡外&#xff0c;还是比较完整的坚持下来了。 从计算机网络--操作系统--MySQL--Redis--C基础&#xff0c;虽然这些知识都有看过…...

Debian 12上安装google chrome

当前系统&#xff1a;Debian 12.7 昨天在Debian 12.7上安装Google Chrome时&#xff0c;可能由于网络原因&#xff0c;导入公钥始终失败。 导致无法正常使用命令#apt install google-chrome-stable来安装google chrome; 解决办法&#xff1a; Step1.下载当前google chrome稳…...

Python | Leetcode Python题解之第405题数字转换为十六进制数

题目&#xff1a; 题解&#xff1a; CONV "0123456789abcdef" class Solution:def toHex(self, num: int) -> str:ans []# 32位2进制数&#xff0c;转换成16进制 -> 4个一组&#xff0c;一共八组for _ in range(8):ans.append(num%16)num // 16if not num:b…...

定位坐标系

定位坐标系是地理空间信息系统中用于确定物体位置的重要工具&#xff0c;它基于数学和物理原理&#xff0c;通过一系列参数来描述物体在地球或其他天体表面的位置。以下是对定位坐标系的详细解析&#xff1a; 一、定义与分类 定位坐标系是根据一定的规则和方法&#xff0c;将…...

安全通信网络等保

通用要求 1.网络架构 1)应保证网络设备的业务处理能力满足业务高峰期需要。 设备CPU和内存使用率的峰值不大于设备处理能力的70%。 在有监控环境的条件下,应通过监控平台查看主要设备在业务高峰期的资源(CPU、内存等)使用 情况;在无监控环境的情况下,在业务高峰期登录…...

7--SpringBoot-后端开发、原理详解(面试高频提问点)

目录 SpringBoot原理 起步依赖 自动配置 配置优先级 Bean设置 获取Bean 第三方Bean SpringBoot原理 内容偏向于底层的原理分析 基于Spring框架进行项目的开发有两个不足的地方&#xff1a; 在pom.xml中依赖配置比较繁琐&#xff0c;在项目开发时&#xff0c;需要自己去找…...

wordpress主题摘要调用显示错误解决办法

如果你的wordpress主题使用了 mb_strimwidth(strip_tags(apply_filters(the_content, $post->post_content)), 0, 360, …); 这样的方式调用内容摘要 如果在主题摘要调用的地方显示错误&#xff0c;导致这个错误的原因是php没有开启&#xff1a;mbstring 开启mbstring的…...

【ESP32】ESP-IDF开发 | UART通用异步收发传输器+串口收发例程

1. 简介 UART可以说是开发者使用得最多的外设之一了&#xff0c;打印log几乎都是使用串口来实现的。UART是一种异步全双工的通信方式&#xff0c;异步传输的特性使得它仅需2根线就可以完成全双工的传输&#xff0c;但这也要求发送端和接收端的速率、停止位、奇偶校验位等都要相…...

2025秋招LLM大模型多模态面试题(六)-KV缓存

目录 为什么Transformer推理需要KV缓存?KV缓存的具体实现 没有缓存的情况下使用缓存的情况下KV缓存在解码中的阶段划分 Prefil阶段Decoding阶段KV缓存的存储类型及显存占用计算KV缓存的局限与优化策略 超长文本与复杂模型场景下的瓶颈量化方案的应用量化方案的副作用与优化方法…...

Modbus转Ethernet IP赋能挤出吹塑机智能监控

在现代工业自动化领域&#xff0c;小疆智控Modbus转Ethernet IP网关GW-EIP-001与挤出吹塑机的应用越来越广泛。这篇文章将为您详细解读这两者的结合是如何提高生产效率&#xff0c;降低维护成本的。首先了解什么是Modbus和Ethernet IP。Modbus是一种串行通信协议&#xff0c;它…...

leetcode 3403. 从盒子中找出字典序最大的字符串 I 中等

给你一个字符串 word 和一个整数 numFriends。 Alice 正在为她的 numFriends 位朋友组织一个游戏。游戏分为多个回合&#xff0c;在每一回合中&#xff1a; word 被分割成 numFriends 个 非空 字符串&#xff0c;且该分割方式与之前的任意回合所采用的都 不完全相同 。所有分…...

VSCode 工作区配置文件通用模板(CMake + Ninja + MinGW/GCC 编译器 的 C++ 或 Qt 项目)

下面是一个通用模板&#xff0c;适用于大多数使用 VSCode CMake Ninja MinGW/GCC 编译器 的 C 或 Qt 项目。你可以将这个 .vscode 文件夹复制到你的项目根目录下&#xff0c;稍作路径调整即可使用。 &#x1f4c1; .vscode/ 目录结构&#xff08;通用模板&#xff09; .vs…...

Flask 应用的生产环境部署指南

Flask 是一个轻量级的 Python Web 应用框架&#xff0c;常用于快速开发 Web 应用或 API。然而&#xff0c;Flask 内置的开发服务器仅适用于开发和调试阶段&#xff0c;并不适合直接用于生产环境。本文将详细介绍在生产环境中部署 Flask 应用的最佳实践&#xff0c;包括使用专业…...

Redis最佳实践——电商应用的性能监控与告警体系设计详解

Redis 在电商应用的性能监控与告警体系设计 一、原子级监控指标深度拆解 1. 内存维度监控 核心指标&#xff1a; # 实时内存组成分析&#xff08;单位字节&#xff09; used_memory: 物理内存总量 used_memory_dataset: 数据集占用量 used_memory_overhead: 管理开销内存 us…...

基于 ZYNQ 的实时运动目标检测系统设计

摘 要: 传统视频监控系统在实时运动目标检测时&#xff0c;存在目标检测不完整和目标检测错误的局限 性 。 本研究基于体积小 、 实时性高的需求&#xff0c;提出了一种将动态三帧差分法与 Sobel 边缘检测算法结 合的实时目标检测方法&#xff0c;并基于 ZYNQ 构建了视频…...

网络编程及原理(一)

目录 一 . 独立模式与网络互联 二 . 局域网 —— LAN &#xff08;1&#xff09;基于网线直连 &#xff08;2&#xff09;基于集线器组建 &#xff08;3&#xff09;基于交换机组建 &#xff08;4&#xff09;基于交换机和路由器组建 三 . 广域网 —— WAN 四 …...

从OCR到Document Parsing,AI时代的非结构化数据处理发生了什么改变?

智能文档处理&#xff1a;非结构化数据提出的挑战 在这个时代的每一天&#xff0c;无论是个人处理账单&#xff0c;还是企业处理合同、保险单、发票、报告或成堆的简历&#xff0c;我们都深陷在海量的非结构化数据之中。这类数据不像整齐排列的数据库表格那样规整&#xff0c;…...

网页前端开发(基础进阶3--Vue)

Vue3 Vue是一款用于构建用户界面的渐进式的JavaScript框架。 Vue由2部分组成&#xff1a;Vue核心包&#xff0c;Vue插件包 Vue核心包包含&#xff1a;声明式渲染&#xff0c;组件系统。 Vue插件包&#xff1a;VueRouter&#xff08;客户端路由&#xff09;&#xff0c;Vuex…...

Day43 Python打卡训练营

作业&#xff1a; kaggle找到一个图像数据集&#xff0c;用cnn网络进行训练并且用grad-cam做可视化 进阶&#xff1a;并拆分成多个文件 选取Kaggle上的CIFAR-10数据集进行CNN训练&#xff0c;并使用Grad-CAM进行可视化&#xff0c;代码将拆分为多个文件以保持模块化。CIFAR-10是…...