深入浅出mysql海量数据批量更新插入、批量查询

1. mysql的批量写

mysql 批量插入可以用下面这种,在values 之后跟上各种多个值列表。但这种写法可能导致sql长度超长、锁超时等问题。

insert into (`field1`,`field1`,`field1`,) values (value01,value02,value03),(value11,value12,value13),(value21,value22,value23) .....;

在数据量较大的时候,上面这种方式就不太合适。mysql提供了批量写入的方法,将大批量的sql脚本一批次发送到服务端,减少IO次数,然后统一一次执行sql。这种写入效率会高很多。如下所示,先执行statement.addBatch()先将sql添加到statement列表,然后执行statement.executeBatch()统一批量执行sql。mybatis-plus的批量提交的底层实现就是基于此,它默认将1000条sql作为一个批次。

      Class.forName("com.mysql.cj.jdbc.Driver");
            // 创建连接
            conn = DriverManager.getConnection(url, user, password);
            // 创建预编译 sql 对象
            statement = conn.prepareStatement("UPDATE sku_inventory set stock =stock+1  where id = ?");
            long a = System.currentTimeMillis(); // 计时
            // 这里添加 100 个批处理参数
            for (int i = 1; i <= 10000; i++) {
                statement.setInt(1, i);
                statement.addBatch(); // 批量添加
            }
            long b = System.currentTimeMillis(); // 计时
            System.out.println("添加参数耗时:" + (b-a)); // 计时
            int[] r = statement.executeBatch(); // 批量提交
            statement.clearBatch(); // 清空批量添加的 sql 命令列表缓存

理论上,上面的sql是批量提交到mysql server统一执行的,但在默认情况下实际上它还是一条条执行命令,要真正的批量执行sql,需要在jdbc连接url加上rewriteBatchedStatements=true,这个参数的默认只是false
在这里插入图片描述
从wireshark抓包的情况来看,在默认配置下,sql批量执行貌似没起作用。这里客户端发送一个sql脚本然后得到一个response响应,发送一个sql得到一个响应,循环万福,就是在串行化执行sql。
在这里插入图片描述
下面是添加了rewriteBatchedStatements=true这个参数后的抓包截图,jdbc客户端重写了sql语句,它把多个sql语句用分号分隔连接在一起,形成一个大sql脚本, 然后将这个sql脚本一次性发送到server端,最后接收到了大量的response响应。这个才是我们想要的接口
在这里插入图片描述
rewriteBatchedStatements这个参数不只是对插入数据有效,对update delete语句也有同样的效果。

另外如果有更大批量的结构化数据需要插入,可以使用 load data local infile这个指令,这个指令可以将文本文件中的数据快速导入到mysql,这个指令比普通的语句快20倍以上。本地测试在没有激烈的锁竞争情况下插入100万数据只用了10秒钟,当然在真实环境中要考虑文本文件传输的I/O耗时,这会增加更多的耗时。
这个指令一般和replace into insert into 结合起来使用。

        load data local infile {fileName} -- 文本文件名
            replace into table sku_inventory  -- 表名
            CHARACTER SET utf8mb4 -- 文本文件的字符集编码
            COLUMNS TERMINATED by ',' -- 文本文件的字段分隔符
        IGNORE 1 lines -- 忽略一行,从第二行读数据因为我的csv文件第一行是字段名
            (`id`, stock,spu_id,`name`)

这个指令需要指定数据文件名、 字符集编码、文本文件的字段分隔符,数据库的字段名列表(注意和文本文件中字段列的顺序一致)
注意:要使用这功能需要先在服务端将环境变量 local_infileon,表示启用这个特性。另外之外还要在客户端启动这个功能,在jdbc连接url上加上参数allowLoadLocalInfile=true

在这里插入图片描述

2. 批量读

大数据的查询需要渐进式查询,如果用普通的查询可能导致mysql数据报文太大、JVM内存溢出等问题。
mysql上有两种解决方案,(1) 游标查询;(2)流式查询。
国内一般都用mybatis做orm框架,现在用mybatis实现这两种功能。
mybatis提供了org.apache.ibatis.cursor.Cursor进行游标查询,但这本质上还是客户端的游标查询,实际上还是一次性从mysql服务器检索出所有数据。不信,请往下看。

1) 游标查询

在这里插入图片描述

<select id="fetchAll" fetchSize="10000" resultMap="BaseResultMap">
        SELECT <include refid="Base_Column_List" />
        FROM sku_inventory WHERE  id > #{gtId}
    </select>

从上面可以看到我定义了一个游标结果集类型的接口,且定义了fetchSize,
但是从com.mysql.cj.protocol.a.BinaryResultsetReader#read方法可以看到,客户端一次性获取到了所有的数据,它是一个静态结果集,并没有分段渐进获取。

在这里插入图片描述

现在我在连接参数上加上useCursorFetch=true,重启项目再执行接口。再看看debug时截图信息,现在结果集是游标类型结果集ResultsetRowsCursor。而且从wirekshar抓包来看,还出现了Fetch Data这个数据报文,这个数据报文内容是10000,这恰好和xml中配置的fetchSize="10000"对应上了。在之前的那个示例中,没加useCursorFetch连接参数,jdbc客户端是没有Fetch Data数据报文的。

2)流式查询

流式查询也可以用org.apache.ibatis.cursor.Cursor实现,只需要将fetchSize设为-2147483648即可启用。为啥是-2147483648尼,因为这个值是Integer的最小值Integer.MIN_VALUE。mysql驱动判断是否是流式查询的方法在com.mysql.cj.jdbc.StatementImpl#createStreamingResultSet中,它的判断逻辑是:
结果集类型是FORWARD_ONLY 、结果集并发类型是CONCUR_READ_ONLYfetchSizeInteger.MIN_VALUE 就启用流式结果集。其中ResultType默认是FORWARD_ONLYresultSetConcurrency默认是CONCUR_READ_ONLY,所以我们只要保证fetchSizeInteger.MIN_VALUE ,那么就可以启用流式结果集。
在这里插入图片描述

mybatis xml中修改下fetchSize参数,其他的不用变更(这里得先把参数useCursorFetch恢复成默认值false)

    <select id="fetchAll" fetchSize="-2147483648" resultMap="BaseResultMap">
        SELECT <include refid="Base_Column_List" />
        FROM sku_inventory WHERE  id > #{gtId}
    </select>

从下面的截图可以看出,此时返回结构是流式结果集ResultsetRowsStreaming

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/680873.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LLM推理加速原理(一)

1.大语言模型的基本结构 transfomer block: 输入--->正则化-->qkv三个矩阵层(映射到三个不同空间中)---->q,k,v之后self attention进行三0合一---->线性映射,正则化。 2.大语言模型的推理 目前主流的语言大模型都采用decoder-only的结构,其推理过程由两部分…

ubuntu22.04编译OpenCV4.9(带contrib-4.9.0)

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;4.9.0 opencv_contrib版本&#xff1a;4.9.0 源码下载 OPenCV4.9.0下载地址&#xff1a;https://github.com/opencv/opencv/releases/tag/4.9.0 如下图所示&#xff1a; 按箭头所指点击下载source code(tar.gz)文件到…

TG-5510CA温补晶振用于GPS应用

随着现代社会对精准定位和导航需求的不断增加&#xff0c;GPS&#xff08;全球定位系统&#xff09;已成为我们日常生活和各行各业中不可或缺的一部分。无论是在智能手机、汽车导航、无人机飞行控制&#xff0c;还是在精密的科学研究和军事应用中&#xff0c;GPS系统都扮演着至…

【杂谈】AIGC之Stable Diffusion:AI绘画的魔法

Stable Diffusion&#xff1a;AI绘画的魔法 引言 在AI的世界里&#xff0c;Stable Diffusion就像一位魔法师&#xff0c;它能够将我们脑海中的幻想&#xff0c;用画笔一一描绘出来。今天&#xff0c;就让我们一探这位魔法师的奥秘&#xff0c;看看它是如何从无到有&#xff0…

clickhouse学习笔记(一)入门与安装

目录 一 、入门 简介 核心特性包括 1.1 列式存储 1.2 原生压缩 1.3 向量化执行引擎 1.4 DBMS 功能 1.5 分布式处理 1.6 高吞吐写入能力 1.7 实时分析 1.8 SQL支持 1.9 高度可扩展 1.10 数据分区与线程级并行 1.11 应用场景 1.12 不适用场景 二、ClickHouse单机版…

【Qt】定时器播放多张图片,动画效果

1. 效果 2. 代码 2.1 头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr);~Widget();void initGif(QS…

MT3051 区间gcd

思路&#xff1a; ST表&#xff0c;ST表模板可参考MT3024 maxmin 注意&#xff0c;这里使用快读快写避免超时 代码&#xff1a; #include <bits/stdc.h> using namespace std; const int N 1e6 10; int n, m, a[N], mn[N][20], Lg[N], l, r, ans; void pre() {Lg[1…

python中的循环语句

while循环 基本语法格式 while 条件&#xff1a; 循环体 条件为真&#xff0c;则执行循环体代码 条件为假&#xff0c;则结束循环 打印 1-10的整数 死循环有时候也是必须的&#xff0c; while语句的语法&#xff1a; &#xff08;1&#xff09;变量的初始化&#xff0c;…

Clo3D导出服装动画,使用Unity3D展示

1.前言 Clo3D是一款应用于时装行业的3D服装设计软件,其强大的布料模拟算法可在3D空间中实现设计、制版、试衣和走秀,大幅提升数字作品逼真度和制作效率。为了让服装动画效果展示在Unity3D上模拟效果&#xff0c;需要Clo3D模拟出逼着的衣服动画。总体流程为Clo3D - Mixamo -Blen…

The 18th Northeast Collegiate Programming Contest(5/9/13)

心得 赛中ac&#xff1a;5&#xff0c;目前ac&#xff1a;9&#xff0c;题目总数&#xff1a;13 中档可做题还是很多的&#xff0c;可惜遇到了难绷的queueforces&#xff0c; 最后15min才判出来&#xff0c;oi赛制5wa4遗憾离场&#xff0c;赛后把几个题都给调过了&#xff0…

遗传算法+神经网络!基于遗传-神经网络(GA-BP)算法的光伏出力预测程序代码!

前言 准确地预测光伏发电出力对于电力系统运营和稳定性至关重要。随着预测技术的不断进步&#xff0c;越来越多的研究者逐渐意识到遗传算法在优化神经网络在新能源出力预测中的潜力。遗传算法是一种模拟生物进化过程的优化算法&#xff0c;通过不断迭代和选择&#xff0c;搜索…

期望18K,4年前端Cvte 视源股份一面挂

一面 1、自我介绍&#xff1f;毕业的时候一直在 xx 公司&#xff0c;你基本都在做什么项目&#xff1f; 2、你讲一下你主要负责哪一块的&#xff1f;balabala 3、你们的 json 是怎么定义组件间的联动的&#xff1f; 4、怎么确定区分两个 input&#xff1f; 5、你们是怎么触…

聚观早报 | 苹果预热WWDC24;怪兽充电第一季度营收

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 6月5日消息 苹果预热WWDC24 怪兽充电第一季度营收 vivo Watch GT设计细节 长城汽车关闭欧洲总部 小米MIX Flip将…

电商架构浅析

前言 什么是电商&#xff0c;电商有哪些分类&#xff0c;以及一个完整的电商平台应该由哪些模块组成&#xff1f;本文将围绕电商平台系统的整体架构展开分析。 一、简介 1. 什么是电商 简单说就是通过网络进行的商务活动。以前的人都是通过现金进行交易&#xff0c;就是所谓的…

热贡文化旅游APP的设计与实现-计算机毕业设计源码69932

摘 要 21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的重要性已逐渐被人们所认识&#xff0c;科学化的管理&#xff0c;使信息存…

专业开放式耳机什么牌子更好?六大技巧教你不踩坑!

相信很多入坑的朋友再最开始挑选耳机的时候都会矛盾&#xff0c;现在市面上这么多耳机&#xff0c;我该怎么选择&#xff1f;其实对于开放式耳机&#xff0c;大家都没有一个明确的概念&#xff0c;可能会为了音质的一小点提升而耗费大量的资金&#xff0c;毕竟这是一个无底洞。…

LabVIEW源程序安全性保护综合方案

LabVIEW源程序安全性保护综合方案 一、硬件加密保护方案 选择和安装硬件设备 选择加密狗和TPM设备&#xff1a;选择Sentinel HASP加密狗和支持TPM&#xff08;可信平台模块&#xff09;的计算机主板。 安装驱动和开发工具&#xff1a;安装Sentinel HASP加密狗的驱动程序和开发…

在加拿大寻求2亿美元融资!Xanadu的CEO有话要说

内容来源&#xff1a;量子前哨&#xff08;ID&#xff1a;Qforepost&#xff09; 文丨慕一/娴睿 排版丨沛贤 深度好文&#xff1a;1500字丨5分钟阅读 摘要&#xff1a;加拿大光量子计算头部企业Xanadu希望在加拿大筹集1-2亿美元&#xff0c;用于建立量子数据中心。虽然融资不…

编译和运行qemu-uboot-arm64单板的Armbian系统

这篇文章ARM虚拟机安装OMV-CSDN博客遗留一个启动qemu-uboot-arm64单板Armbian镜像的问题&#xff0c;使用官方下载的镜像&#xff0c;会报错&#xff1a; fatal: no kernel available .... Failed to load /vmlinuz ...... qemu-system-aarch64 -smp 8 -m 8G -machine virt …

绿联Nas docker 中 redis 老访问失败的排查

部署了一些服务&#xff0c;老隔3-5 天其他服务就联不上 redis 了&#xff0c;未确定具体原因&#xff0c;只记录观察到的现象 宿主机访问 只有 ipv6 绑定了&#xff0c;ipv4 绑定挂掉了 其他容器访问 也无法访问成功 当重启容器后&#xff1a; 一切又恢复正常。 可能的解…