MySQL批量插入4种方案(对比速度起飞)

news2024/11/15 16:33:40
  • 一、前言

  • 二、准备工作

  • 1、Maven项目中pom.xml文件引入的相关依赖如下

  • 2、application.yml配置属性文件内容(重点:开启批处理模式)

  • 3、Entity实体类(测试)

  • 4、数据库student表结构(注意:无索引)

  • 三、测试工作

  • 1、for循环插入(单条)(总耗时:177秒)

  • 2、拼接SQL语句(总耗时:2.9秒)

  • 3、批量插入saveBatch(总耗时:2.7秒)

  • 4、循环插入 + 开启批处理模式(总耗时:1.7秒)(重点:一次性提交)

  • 四、总结


简明:本文记录个人使用MySQL插入大数据总结较实用的方案,通过对常用插入大数据的4种方式进行测试,即for循环单条、拼接SQL、批量插入saveBatch()、循环 + 开启批处理模式,得出比较实用的方案心得。

一、前言

最近趁空闲之余,在对MySQL数据库进行插入数据测试,对于如何快速插入数据的操作无从下手,在仅1W数据量的情况下,竟花费接近47s,实在不忍直视!在不断摸索之后,整理出一些较实用的方案。

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
项目地址: https://github.com/YunaiV/ruoyi-vue-pro
视频教程: https://doc.iocoder.cn/video/

二、准备工作

测试环境:SpringBoot项目、MyBatis-Plus框架、MySQL8.0.24、JDK13
前提:SpringBoot项目集成MyBatis-Plus上述文章有配置过程,同时实现IService接口用于进行批量插入数据操作saveBatch()方法

1、Maven项目中pom.xml文件引入的相关依赖如下

<dependencies>  <!-- SpringBoot Web模块依赖 -->  <dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-web</artifactId>  </dependency>  <!-- MyBatis-Plus 依赖 -->  <dependency>    <groupId>com.baomidou</groupId>    <artifactId>mybatis-plus-boot-starter</artifactId>    <version>3.3.1</version>  </dependency>  <!-- 数据库连接驱动 -->  <dependency>    <groupId>mysql</groupId>    <artifactId>mysql-connector-java</artifactId>  </dependency>  <!-- 使用注解,简化代码-->  <dependency>    <groupId>org.projectlombok</groupId>    <artifactId>lombok</artifactId>  </dependency></dependencies>

2、application.yml配置属性文件内容(重点:开启批处理模式)

server:    端口号     port: 8080#  MySQL连接配置信息(以下仅简单配置,更多设置可自行查看)spring:    datasource:         连接地址(解决UTF-8中文乱码问题 + 时区校正)                (rewriteBatchedStatements=true 开启批处理模式)        url: jdbc:mysql://127.0.0.1:3306/bjpowernode?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true         用户名        username: root         密码        password: xxx         连接驱动名称        driver-class-name: com.mysql.cj.jdbc.Driver

3、Entity实体类(测试)

/** *   Student 测试实体类 *    *   @Data注解:引入Lombok依赖,可省略Setter、Getter方法 */@Data@TableName(value = "student")public class Student {        /**  主键  type:自增 */    @TableId(type = IdType.AUTO)    private int id;    /**  名字 */    private String name;    /**  年龄 */    private int age;    /**  地址 */    private String addr;    /**  地址号  @TableField:与表字段映射 */    @TableField(value = "addr_num")    private String addrNum;    public Student(String name, int age, String addr, String addrNum) {        this.name = name;        this.age = age;        this.addr = addr;        this.addrNum = addrNum;    }}

4、数据库student表结构(注意:无索引)

三、测试工作

简明:完成准备工作后,即对for循环、拼接SQL语句、批量插入saveBatch()、循环插入+开启批处理模式,该4种插入数据的方式进行测试性能。
注意:测试数据量为5W、单次测试完清空数据表(确保不受旧数据影响)
( 以下测试内容可能受测试配置环境、测试规范和数据量等诸多因素影响,读者可自行结合参考进行测试 )

1、for循环插入(单条)(总耗时:177秒)

总结:测试平均时间约是177秒,实在是不忍直视(捂脸),因为利用for循环进行单条插入时,每次都是在获取连接(Connection)、释放连接和资源关闭等操作上,(如果数据量大的情况下)极其消耗资源,导致时间长。
@GetMapping("/for")public void forSingle(){    // 开始时间    long startTime = System.currentTimeMillis();    for (int i = 0; i < 50000; i++){        Student student = new Student("李毅" + i,24,"张家界市" + i,i + "号");        studentMapper.insert(student);    }    // 结束时间    long endTime = System.currentTimeMillis();    System.out.println("插入数据消耗时间:" + (endTime - startTime));}

(1)第一次测试结果:190155 约等于 190秒

(2)第二次测试结果:175926 约等于 176秒(服务未重启)

(3)第三次测试结果:174726 约等于 174秒(服务重启)

2、拼接SQL语句(总耗时:2.9秒)

简明:拼接格式:insert into student(xxxx) value(xxxx),(xxxx),(xxxxx).......
总结:拼接结果就是将所有的数据集成在一条SQL语句的value值上,其由于提交到服务器上的insert语句少了,网络负载少了,性能也就提上去。但是当数据量上去后,可能会出现内存溢出、解析SQL语句耗时等情况,但与第一点相比,提高了极大的性能。
@GetMapping("/sql")public void sql(){    ArrayList<Student> arrayList = new ArrayList<>();    long startTime = System.currentTimeMillis();    for (int i = 0; i < 50000; i++){        Student student = new Student("李毅" + i,24,"张家界市" + i,i + "号");        arrayList.add(student);    }    studentMapper.insertSplice(arrayList);    long endTime = System.currentTimeMillis();    System.out.println("插入数据消耗时间:" + (endTime - startTime));}// 使用@Insert注解插入:此处为简便,不写Mapper.xml文件@Insert("<script>" +        "insert into student (name,age,addr,addr_num) values " +        "<foreach collection='studentList' item='item' separator=','> " +        "(#{item.name},{item.age},{item.addr},{item.addrNum}) " +        "</foreach> " +        "</script>")int insertSplice(@Param("studentList") List<Student> studentList);

(1)第一次测试结果:3218 约等于 3.2秒

(2)第二次测试结果:2592 约等于 2.6秒(服务未重启)

(3)第三次测试结果:3082 约等于 3.1秒(服务重启)

3、批量插入saveBatch(总耗时:2.7秒)

简明:使用MyBatis-Plus实现IService接口中批处理saveBatch()方法,对底层源码进行查看时,可发现其实是for循环插入,但是与第一点相比,为什么性能上提高了呢?因为利用分片处理(batchSize = 1000) + 分批提交事务的操作,从而提高性能,并非在Connection上消耗性能。
@GetMapping("/saveBatch1")public void saveBatch1(){    ArrayList<Student> arrayList = new ArrayList<>();    long startTime = System.currentTimeMillis();    // 模拟数据    for (int i = 0; i < 50000; i++){        Student student = new Student("李毅" + i,24,"张家界市" + i,i + "号");        arrayList.add(student);    }    // 批量插入    studentService.saveBatch(arrayList);    long endTime = System.currentTimeMillis();    System.out.println("插入数据消耗时间:" + (endTime - startTime));}

(1)第一次测试结果:2864 约等于 2.9秒

(2)第二次测试结果:2302 约等于 2.3秒(服务未重启)

(3)第三次测试结果:2893 约等于 2.9秒(服务重启)

重点注意:MySQL JDBC驱动默认情况下忽略saveBatch()方法中的executeBatch()语句,将需要批量处理的一组SQL语句进行拆散,执行时一条一条给MySQL数据库,造成实际上是分片插入,即与单条插入方式相比,有提高,但是性能未能得到实质性的提高。
测试:数据库连接URL地址缺少 rewriteBatchedStatements = true 参数情况
#  MySQL连接配置信息spring:    datasource:         连接地址(未开启批处理模式)        url: jdbc:mysql://127.0.0.1:3306/bjpowernode?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai         用户名        username: root         密码        password: xxx         连接驱动名称        driver-class-name: com.mysql.cj.jdbc.Driver

测试结果:10541 约等于 10.5秒(未开启批处理模式)

4、循环插入 + 开启批处理模式(总耗时:1.7秒)(重点:一次性提交)

简明:开启批处理,关闭自动提交事务,共用同一个SqlSession之后,for循环单条插入的性能得到实质性的提高;由于同一个SqlSession省去对资源相关操作的耗能、减少对事务处理的时间等,从而极大程度上提高执行效率。(目前个人觉得最优方案)
@GetMapping("/forSaveBatch")public void forSaveBatch(){    //  开启批量处理模式 BATCH 、关闭自动提交事务 false    SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH,false);    //  反射获取,获取Mapper    StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);    long startTime = System.currentTimeMillis();    for (int i = 0 ; i < 50000 ; i++){        Student student = new Student("李毅" + i,24,"张家界市" + i,i + "号");        studentMapper.insertStudent(student);    }    // 一次性提交事务    sqlSession.commit();    // 关闭资源    sqlSession.close();    long endTime = System.currentTimeMillis();    System.out.println("总耗时: " + (endTime - startTime));}

(1)第一次测试结果:1831 约等于 1.8秒

(2)第二次测试结果:1382 约等于 1.4秒(服务未重启)

(3)第三次测试结果:1883 约等于 1.9秒(服务重启)

四、总结

本文记录个人学习MySQL插入大数据一些方案心得,可得知主要是在获取连接、关闭连接、释放资源和提交事务等方面较耗能,其中最需要注意是开启批处理模式,即URL地址的参数:rewriteBatchedStatements = true,否则也无法发挥作用。对于测试方案的设定、对考虑不周、理解和编写错误的地方等情况,请多指出,共同学习!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

4.2 避免缩进错误

4.1.3 在for循环结束后执行一些操作for循环结束后再怎么做呢?通常,你需要提供总结性输出或接着执行程序必须完成的其他任务。在for循环后面&#xff0c;没有缩进的代码都只执行一次&#xff0c;而不会重复执行。下面来打印一条向全体魔术师致谢的消息&#xff0c;感谢他们的精…

爬虫实例(一) —— 5行 Python 代码爬取

大家好&#xff0c;我是 Enovo飞鱼&#xff0c;今天分享一个爬虫小案例&#xff0c;小白或者爬虫入门的小伙伴推荐阅读&#xff0c;加油&#x1f4aa;。 目录 前言 基本环境配置 爬取目标网站 爬取内容 实现代码 后面我会继续更新爬虫实例&#xff0c;与大家共同学习&am…

ubuntu设置双网卡以及多网段

前提设备有两个网卡&#xff0c;分别作为内网和外网,比如两个网卡eth0和eth1,eth0作为外网&#xff0c;eth1作为内网&#xff0c;每个人的网卡名称可能不一样&#xff0c;网卡名称可以自行查看&#xff0c;使用ifconfig命令&#xff1a;ifconfig区分内网和外网的ip外网网卡&…

如何使用 Apache IoTDB 中的 UDF

本篇作者&#xff1a;IoTDB 社区 -- 廖兰宇本文将概述用户使用 UDF 的大致流程&#xff0c;UDF 的详细使用说明请参考官网用户手册&#xff1a;https://iotdb.apache.org/zh/UserGuide/Master/Operators-Functions/User-Defined-Function.html1编写 UDFIoTDB 为用户提供编写 UD…

opensuse15.4安装android-studio-2021.1.1.23_未完成

opensuse15.4安装android_studio再运行微信apk_未完成 未完成的原因是&#xff1a;本人台式机的物理内存为4G&#xff0c;官方要求是16G android studio与android sdkj是两个完全不同的两样东西。 Android studio是一个IDE&#xff08;可视化开发工具&#xff09;跟eclipse一…

SAP 新准则IFRS 17:重新思考和革新保险会计的机会

您准备好迎接 IFRS 17 了吗&#xff1f;财务报告准则过去曾多次更改&#xff0c;但这次没有。这一变化将为准备迎接新准则的保险公司带来广泛的机遇。许多公司都有应对这些要求的战术计划。但最大的成功将由制定包括 IFRS 17 在内的更广泛报告战略的公司实现。他们不会做出回应…

redis-哈希槽一致hash算法

1、一致性hash算法&#xff1f; 以分布式缓存为例&#xff0c;假设现在有3台缓存服务器(S0&#xff0c;S1&#xff0c;S2)&#xff0c;要将一些图片尽可能平均地分配到不同的服务器上&#xff0c;hash算法的做法是&#xff1a; (1) 以图片的名称作为key&#xff0c;然后对其做…

【Unity3D插件】UniRx(基于Unity的响应式编程框架)插件教程

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址我的个人博客QQ群&#xff1a;1040082875 大家好&#xff0c;我是佛系工程师☆恬静的小魔龙☆&#xff0c;不定时更新Unity开发技巧&#xff0c;觉得有用记得一键三连哦。 一、介绍UniRx插件 UniRx是一种基于Unity3D的…

九龙证券|石墨烯电池和锂离子电池哪个好

电池技术是电动汽车大力推广和开展的最大门槛&#xff0c;而电池工业正处于铅酸电池和传统锂电池开展均遇瓶颈的阶段&#xff0c;石墨烯储能设备的研制成功后&#xff0c;若能批量生产&#xff0c;则将为电池工业乃至电动车工业带来新的改造。那么石墨烯电池和锂离子电池哪个更…

VUE VS React 对比

VUE VS React 对比 这是面试中经常考察的一个问题&#xff0c;简单整理一下。我主要写 react &#xff0c;所以 react 的特点阐述的多一点。 语法格式 vue 是单独的文件格式&#xff0c;一个文件包括了 js css HTML 全部 React 通常是 jsx 格式&#xff0c;JS 和 HTML 写在…

shiro相关源码解析

1. 认证过程相关源码解析 前后文可接查看 shiro的登陆都是通过subject.login()方法实现&#xff0c;接下来我们就进入login方法查看实现过程&#xff1a; 1.1 进入DelegatingSubject类的login方法&#xff1a; 此类实现了Subject接口&#xff1a; public void login(Authen…

基于ssm的高校二手物品交易网 java idea mysql

本文论述了民办高校二手物品交易网的设计和实现&#xff0c;该网站从实际运用的角度出发&#xff0c;运用了计算机网站设计、数据库等相关知识&#xff0c;网络和Mysql数据库设计来实现的&#xff0c;网站主要包括用户注册、用户登录、浏览商品、搜索商品、查看商品并进行购买&…

bilibili全链路压测改造之全链自动化测试实践

01 、背景与意义 B站直播营收送礼业务有着高写、在跨晚和S赛等大型活动下流量陡增、数据实时性要求高等特性&#xff0c;传统压测对于写场景为了避免影响线上数据做了各种屏蔽和黑名单处理&#xff0c;有着无法逼近线上真实情况的问题&#xff0c;因此业务对全链路压测有着较大…

拿下阿里自动化测试岗23k*14薪offer的全程面试记录解析以及总结,一面二面三面,项目,功能,自动化,性能测试,面试题问答

一、自我介绍 面试官您好&#xff01;我叫xx&#xff0c;来自深圳&#xff0c;毕业之后一直从事于软件测试的工作&#xff0c;有做过保险、金融、电商等项目&#xff1b;有做过做功能测试、接口测试&#xff0c;自动化测试&#xff0c;在工作中积极主动、可以独立的完成测试工…

shiro(一):shiro基本概念及基本使用(认证、授权)

1. 权限的管理 1.1 什么是权限管理 基本上涉及到用户参与的系统都要进行权限管理&#xff0c;权限管理属于系统安全的范畴&#xff0c;权限管理实现对用户访问系统的控制&#xff0c;按照安全规则或者安全策略控制用户可以访问而且只能访问自己被授权的资源。 权限管理包括用…

算法刷题打卡第76天:判断矩阵是否是一个 X 矩阵

判断矩阵是否是一个 X 矩阵 难度&#xff1a;简单 如果一个正方形矩阵满足下述 全部 条件&#xff0c;则称之为一个 X 矩阵 &#xff1a; 矩阵对角线上的所有元素都 不是 0 矩阵中所有其他元素都是 0 给你一个大小为 n x n 的二维整数数组 grid &#xff0c;表示一个正方形矩…

CV——day72:从零开始学YOLO——YOLO-v3(可以在我的资源里下载完整的v1到v3的笔记啦!)

YOLO-v36. YOLO-v36.1 YOLO-v3 改进综述6.2 多scale方法改进与特征融合6.3 经典变换方法对比分析6.4 残差连接方法解读6.5 整体网络模型架构分析6.6 先验框设计改进6.7 softmax层改进6. YOLO-v3 **tips&#xff1a;**作者本人因为美军广泛运用于军事领域&#xff0c;所以决定不…

基于php电影点播平台/电影网站

摘要网络技术给生活带来了十分的便利。所以把电影点播平台与现在网络相结合。在点播平台发展的整个过程中&#xff0c;电影信息管理担负着最重要的角色。为满足如今日益复杂的管理需求&#xff0c;各类电影信息管理程序也在不断改进。本课题所设计的电影点播平台&#xff0c;使…

张艺谋《满江红》起诉自媒体人,杨语莲推荐周兆成意在下个谋女郎

伴随着兔年春节的到来&#xff0c;又迎来一波贺岁剧热潮&#xff0c;著名导演张艺谋的《满江红》&#xff0c;也如期和观众朋友见面。随着春节的逐渐结束&#xff0c;贺岁电影《满江红》票房&#xff0c;也再次创下了新高&#xff0c;关于这部电影的话题也多了起来。 最引人关注…

中国电子学会2021年12月份青少年软件编程Python等级考试试卷一级真题(含答案)

青少年软件编程&#xff08;Python&#xff09;等级考试试卷&#xff08;一级&#xff09; 一、单选题(共25题&#xff0c;共50分) 1. 昨天的温度是5摄氏度&#xff0c;今天降温7摄氏度&#xff0c;今天的温度是多少摄氏度&#xff1f;&#xff08; &#xff09; A. 12 …