SpringBoot快速插入Mysql 1000万条数据
导读
有时候为了验证系统瓶颈,需要往数据库表中插入大量数据,可以写sheel脚本插入,前几天为了插入100万条数据,走的sheel脚本(点我直达),插入速度简直无法直视,花了3小时,才插入了10万条,后来没辙了,多跑几次sheel脚本(算是多线程操作吧),最终花了4个多小时才插入100万条记录。今天使用java程序快速插入1000万条数据,最终只需要3分钟多一点就搞定了,好了下面开始吧~
添加依赖
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--mybatis plus和spring boot整合-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.0</version>
</dependency>
<!--Druid连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<!-- guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
</dependency>
application.properties
# 端口号
server.port=9999
#===========数据库相关=============
#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#spring.datasource.url=jdbc:mysql://127.0.0.1/shop?useUnicode=true&characterEncoding=utf-8&useSSL=false
#spring.datasource.username=root
#spring.datasource.password=root
# mybatis plus下划线转驼峰
mybatis-plus.configuration.map-underscore-to-camel-case=true
# 配置mybatis plus打印sql日志
#mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
spring.datasource.name=mysql_test
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
# druid配置
# 监控统计拦截的filters
spring.datasource.druid.filters=stat
spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.url=jdbc:mysql://127.0.0.1/yb_mysql?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.druid.username=root
spring.datasource.druid.password=root
#配置初始化大小/最小/最大
spring.datasource.druid.initial-size=1
spring.datasource.druid.min-idle=1
spring.datasource.druid.max-active=20
#获取连接等待超时时间
spring.datasource.druid.max-wait=60000
#间隔多久进行一次检测,检测需要关闭的空闲连接
spring.datasource.druid.min-evictable-idle-time-millis=300000
spring.datasource.druid.validation-query= SELECT 'x'
spring.datasource.druid.test-while-idle=true
spring.datasource.druid.test-on-borrow=true
spring.datasource.druid.test-on-return=false
数据库表结构
实体类
package com.ybchen.domain; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode; import java.io.Serializable; /**
* <p>
* 用户表
* </p>
*
* @author chenyanbin
* @since 2021-11-07
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("user")
public class UserDO implements Serializable { private static final long serialVersionUID = 1L; /**
* 主键
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id; /**
* 姓名
*/
private String name; /**
* 备注
*/
private String remark; }
Mapper
package com.ybchen.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ybchen.domain.UserDO;
import org.apache.ibatis.annotations.Param; import java.util.List; public interface UserMapper extends BaseMapper<UserDO> {
/**
* 批量插入
* @param userList
* @return
*/
int batchInsert(@Param("listUser") List<UserDO> userList);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ybchen.mapper.UserMapper"> <!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.ybchen.domain.UserDO">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="remark" property="remark"/>
</resultMap> <!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, name, remark
</sql> <!-- 批量插入 -->
<insert id="batchInsert">
insert into user (`name`,`remark`)
values
<foreach collection="listUser" item="item" separator=",">
(#{item.name},#{item.remark})
</foreach>
</insert>
</mapper>
Controller
package com.ybchen.controller; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Lists;
import com.ybchen.domain.UserDO;
import com.ybchen.mapper.UserMapper;
import com.ybchen.utils.JsonData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController; import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch; /**
* @Author:chenyanbin
*/
@RestController
public class UserController {
@Autowired
UserMapper userMapper; @GetMapping("batchInsert")
public JsonData batchInsert() {
int num = 2000;
CountDownLatch latch = new CountDownLatch(1);
List<UserDO> userList = new ArrayList<>();
new Thread(() -> {
for (int i = 0; i < 10000000; i++) {
UserDO userDO = new UserDO();
userDO.setName("陈彦斌====》" + i);
userDO.setRemark("博客地址:https://www.cnblogs.com/chenyanbin/");
userList.add(userDO);
}
latch.countDown();
}).start();
try {
latch.await();
} catch (InterruptedException e) {
}
//2000条为一批,插入1000万条
List<List<UserDO>> partition = Lists.partition(userList, num);
partition.stream().forEach(user -> {
int rows = userMapper.batchInsert(user);
System.err.println("插入数据成功,rows:" + rows);
});
return JsonData.buildSuccess();
} @GetMapping("all")
public JsonData all(){
return JsonData.buildSuccess(userMapper.selectList(new LambdaQueryWrapper<>()));
}
}
项目结构
演示
最终耗时
存储过程方式
delimiter ;;
create procedure chenyanbin()
begin
declare i int;
set i=1;
while(i<=3000000)do
insert into test_excel (name1,name2,name3,name4,name5,name6,name7,name8,name9,name10,name11,name12,name13,name14,name15)
values(concat('列1-:',i), concat('列2-:',i), concat('列3-:',i), concat('列4-:',i), concat('列5-:',i), concat('列6-:',i), concat('列7-:',i), concat('列8-:',i), concat('列9-:',i), concat('列10-:',i), concat('列11-:',i), concat('列12-:',i), concat('列13-:',i), concat('列14-:',i), concat('列15-:',i));
set i=i+1;
end while;
end;;
delimiter ;
call chenyanbin();
SpringBoot快速插入Mysql 1000万条数据的更多相关文章
- 绝对干货,教你4分钟插入1000万条数据到mysql数据库表,快快进来
我用到的数据库为,mysql数据库5.7版本的 1.首先自己准备好数据库表 其实我在插入1000万条数据的时候遇到了一些问题,现在先来解决他们,一开始我插入100万条数据时候报错,控制台的信息如下: ...
- 插入1000万条数据到mysql数据库表
转自:https://www.cnblogs.com/fanwencong/p/5765136.html 我用到的数据库为,mysql数据库5.7版本的 1.首先自己准备好数据库表 其实我在插入100 ...
- 1000万条数据导入mysql
今天需要将一个含有1000万条数据的文本内容插入到数据库表中,最初自然想到的是使用Insertinto '表名'values(),(),()...这种插入方式,但是发现这种方式对1000万条数据量的情 ...
- QTreeView处理大量数据(使用1000万条数据,每次都只是部分刷新)
如何使QTreeView快速显示1000万条数据,并且内存占用量少呢?这个问题困扰我很久,在网上找了好多相关资料,都没有找到合理的解决方案,今天在这里把我的解决方案提供给朋友们,供大家相互学习. 我开 ...
- Oracle 快速插入1000万条数据的实现方式
1.使用dual配合connect by level create table BigTable as select rownum as id from dual connect by level & ...
- (C#版本)提升SQlite数据库效率——开启事务,极速插入数据,3秒100万,32秒1000万条数据
SQLite插入数据效率最快的方式就是:开启事务 + insert语句 + 关闭事务(提交) 利用事务的互斥性,如果在批量的插入操作前显式地开启一次事务,在插入操作结束后,提交事务,那么所有 ...
- 教你如何6秒钟往MySQL插入100万条数据!然后删库跑路!
教你如何6秒钟往MySQL插入100万条数据!然后删库跑路! 由于我用的mysql 8版本,所以增加了Timezone,然后就可以了 前提是要自己建好库和表. 数据库test, 表user, 三个字段 ...
- mysql快速导入5000万条数据过程记录(LOAD DATA INFILE方式)
mysql快速导入5000万条数据过程记录(LOAD DATA INFILE方式) 首先将要导入的数据文件top5000W.txt放入到数据库数据目录/var/local/mysql/data/${d ...
- Mysql慢查询开启和查看 ,存储过程批量插入1000万条记录进行慢查询测试
首先登陆进入Mysql命令行 执行sql show variables like 'slow_query%'; 结果为OFF 说明还未开启慢查询 执行sql show varia ...
- 使用hibernate在5秒内插入11万条数据,你觉得可能吗?
需求是这样的,需要查询某几个表的数据,然后插入到另外一个表. 一看到需求,很多人都会用hibernate去把这些数据都查询出来,然后放到list中, 然后再用for循环之类的进行遍历,一条一条的取出数 ...
随机推荐
- MySQL如何快速获取binlog的开始时间和结束时间
之前写过一篇文章MySQL如何获取binlog的开始时间和结束时间[1],文章里面介绍了如何获取MySQL数据库二进制日志(binlog)的开始时间与结束时间的一些方法.实际应用当中,我们可能还会遇到 ...
- 服务器电源管理(Power Management States)
目录 文章目录 目录 EIST(智能降频技术) 硬件 固件 操作系统 EIST(智能降频技术) EIST 能够根据不同的 OS(操作系统)工作量自动调节 CPU 的电压和频率,以减少耗电量和发热量.它 ...
- linux file命令查看文件类型
在linux系统中,linux是不根据后缀名识别文件类型的,所以使用file命令查看文件的类型. [root@node5 ~]# file /etc/shadow /etc/shadow: ASCII ...
- Android 13 - Media框架(6)- NuPlayer
关注公众号免费阅读全文,进入音视频开发技术分享群! 上一节我们通过 NuPlayerDriver 了解了 NuPlayer 的使用方式,这一节我们一起来学习 NuPlayer 的部分实现细节. ps: ...
- 用 AI 速读海量文档!5款 AI 阅读工具推荐
在当今信息爆炸的时代,我们在手动搜集和处理信息时面临着几个挑战: 浩如烟海的信息量远远超出了我们的阅读能力. 信息的复杂性要求我们重复筛选和过滤. 专业或难以理解的内容需要被翻译成易懂的语言. 需要从 ...
- Android启动过程-万字长文(Android14)
在计算机启动过程和Linux内核Kernel启动过程介绍了计算机启动和内核加载,本篇文章主要介绍Android系统是如何启动的. 一.Android启动流程 Android系统的启动流程与Linux接 ...
- vue单个插槽
当子组件模板只有一个没有属性的插槽时,父组件传入的整个内容片段将插入到插槽所在的 DOM 位置,并替换掉插槽标签本身. # 子组件 <div> <h2>我是子组件的标题< ...
- Vue学习:7.计算属性2
上一节了解的是计算属性的默认简写,只能读取,不能修改. 什么意思呢?很简单,我们知道计算属性是依赖数据动态计算一个值,那我可不可以直接this.计算属性 = xxx 来修改计算属性的结果呢?这其实是不 ...
- 有点东西,template可以直接使用setup语法糖中的变量原来是因为这个
前言 我们每天写vue3代码的时候都会使用到setup语法糖,那你知道为什么setup语法糖中的顶层绑定可以在template中直接使用的呢?setup语法糖是如何编译成setup函数的呢?本文将围绕 ...
- Luban小试牛刀
Luban小试牛刀 LubanUnity LubanUnity配置工具配置解决方案 简介 Github 文档 视频教程 Unity工具 个人感觉挺强大,便捷的,适合中大型游戏项目的配置工作.小 ...