MySQL插入大量数据探讨
笔者想进行数据库查询优化探索,但是前提是需要一个很大的表,因此得先导入大量数据至一张表中。
准备工作
准备一张表,id为主键且自增:

方案一
首先我想到的方案就是通过for循环插入
xml文件:
<?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.zy.route.mapper.BigBiaoMapper"> <resultMap id="BaseResultMap" type="com.zy.route.DO.BigBiao">
<id column="id" property="id"/>
<result column="menu" property="menu"/>
<result column="operation" property="operation"/>
<result column="uri" property="uri"/>
<result column="msg" property="msg"/>
<result column="creator" property="creator"/>
</resultMap> <sql id="tableName">
bigbiao
</sql> <sql id="BaseColumn">
`id`, `menu`, `operation`, `uri`, `msg`,`creator`
</sql> <sql id="set">
<if test="id != null">
`id` = #{id},
</if>
<if test="menu != null">
`menu` = #{menu},
</if>
<if test="operation != null">
`operation` = #{operation},
</if>
<if test="uri != null">
`uri` = #{uri},
</if>
<if test="msg != null">
`msg` = #{msg},
</if>
<if test="creator != null">
`creator` = #{creator},
</if>
</sql> <insert id="insertIntoBiao" parameterType="com.zy.route.DO.BigBiao">
insert
<include refid="tableName"/>
<set>
<include refid="set"/>
</set>
</insert> </mapper>
这里我就直接使用SpringBoot的测试类进行插入操作
@SpringBootTest
@RunWith(SpringRunner.class)
public class BigBiaoMapperTest { @Autowired
private BigBiaoMapper bigBiaoMapper; @Test
public void insert() {
BigBiao bigBiao = new BigBiao()
.setMenu("项目资料")
.setOperation("查询项目目录")
.setUri("/project/big/biao")
.setMsg("{\"method\":\"Get\"\",\"\"costTime:95\"\",\"\"ip:255.255.255.0\"}")
.setCreator("LonZyuan");
long start = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
bigBiaoMapper.insertIntoBiao(bigBiao);
}
long end = System.currentTimeMillis();
System.out.println("执行时间:" + (end - start) + "ms");
}
}
执行,查看执行时间:

可以发现,就单单1000条数据,就花了29s多
原因分析(参考MySQL45讲)
首先我们需要了解一条SQL更新语句是如何执行的:

而我方案一中的操作就是,通过for循环,进行了1000次的客户端与数据库的开闭连接,然后每次就写入一条数据,
并且由于表更新后,与该表相关的查询缓存会失效,查询缓存也没用,因此低效是必然的。
方案二
既然一条条插入很慢,那我通过List一次性插入多个不就行了。
xml语句:
<insert id="batchInsert">
insert into
bigbiao
(`menu`, `operation`, `uri`, `msg`,`creator`)
values
<foreach collection="list" item="item" separator=",">
(#{item.menu},#{item.operation},#{item.uri},#{item.msg},#{item.creator})
</foreach>
</insert>
测试类:
@SpringBootTest
@RunWith(SpringRunner.class)
public class BigBiaoMapperTest { @Autowired
private BigBiaoMapper bigBiaoMapper; @Test
public void batchInsert() {
BigBiao bigBiao = new BigBiao()
.setMenu("批量添加2号")
.setOperation("batchAdd")
.setUri("/begin/batch/add/big/biao")
.setMsg("{\"method:Insert\",\"costTime:88\",\"ip:0.0.0.255\",\"添加一堆东西\"}")
.setCreator("LonZyuan");
List<BigBiao> bigBiaos = new ArrayList<>();
long start = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
bigBiaos.add(bigBiao);
}
bigBiaoMapper.batchInsert(bigBiaos);
long end = System.currentTimeMillis();
System.out.println("执行时间:" + (end - start) + "ms");
} }
运行,查看执行时间:

速度很快,那我现在插10w条进去:
@Test
public void batchInsert() {
BigBiao bigBiao = new BigBiao()
.setMenu("批量添加2号")
.setOperation("batchAdd")
.setUri("/begin/batch/add/big/biao")
.setMsg("{\"method:Insert\",\"costTime:88\",\"ip:0.0.0.255\",\"添加一堆东西\"}")
.setCreator("LonZyuan");
List<BigBiao> bigBiaos = new ArrayList<>();
long start = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
bigBiaos.add(bigBiao);
}
bigBiaoMapper.batchInsert(bigBiaos);
long end = System.currentTimeMillis();
System.out.println("执行时间:" + (end - start) + "ms");
}
但是又翻车了:

查一下Packet for query is too large,原来MySQL会根据配置文件,限制Server接受数据包的大小,
图中(16500100 > 4194304)就是具体问题点,4194304 B = 4MB,所以是这个值小了。
解决:
这个参数为 max_allowed_packet ,在 ini 配置文件中设置一下:
max_allowed_packet = 20M
重启MySQL,然后再次运行:

10w条数据插入成功了
这里可能有小伙伴想问那我直接插1000w条进去,那就会发生OOM问题:

这个问题后续在做探讨。
MySQL插入大量数据探讨的更多相关文章
- mysql 插入/更新数据
mysql 插入/更新数据 INSERT 语句 1.一次性列出全部字段的值,例如: INSERT INTO student VALUES('Chenqi','M', 29); INSERT INTO ...
- [转载]mysql插入大量数据
mysql的批量数据格式, 比如 INSERT INTO TABLES (LABLE1,LABLE2,LABLE3,...) VALUES(NUM11,NUM12,NUM13,...), (NUM ...
- C API向MySQL插入批量数据的快速方法——关于mysql_autocommit
MySQL默认的数据提交操作模式是自动提交模式(autocommit).这就表示除非显式地开始一个事务,否则每个查询都被当做一个单独的事务自动执行.我们可以通过设置autocommit的值改变是否是自 ...
- MySQL插入中文数据出现?号
原文转载自:https://blog.csdn.net/LynneZoe/article/details/79174119 运行环境:win10 mysql版本:Mysql5.6 做一个项目的时候,向 ...
- mysql插入中文数据变成问号怎么处理
插入中文数据变成问号,一般都是因为字符集没有设置成utf8的原因 1.修改字符集: ALTER TABLE 表名 MODIFY 列名 类型(50) CHARACTER SET "utf8&q ...
- laravel 解决mysql插入相同数据的问题
1.背景: 每天0点定时任务统计数据,实现目标是统计时如果没有今天的统计数据,那就执行insert操作 如果存在那就执行update操作: 代码逻辑 1 if(报表存在){ 2 update(); 3 ...
- mysql插入表数据中文乱码问题解决方案
一.问题 开发中遇到将其它数据库数据插入到mysql数据库表中一直会报类似如下错误: Incorrect string value: '\xE6\x88\x91' for column 'name' ...
- MySQL插入大批量数据时报错“The total number of locks exceeds the lock table size”的解决办法
事情的原因是:我执行了一个load into语句的SQL将一个很大的文件导入到我的MySQL数据库中,执行了一段时间后报错"The total number of locks exceeds ...
- MySQL 插入 中文数据乱码解决
问题描述: 1.在命令行中进行插入,没有问题.但是显示存在部分乱码 2.在JDBC中插入成功.中文是直接以“??”形式显示. 通过Navicat客户端查看 与在网页中看到的一一致,说明读取没有问题,问 ...
随机推荐
- 热身训练4 Article
Article 在这个学期即将结束时,DRD开始写他的最后一篇文章. DRD使用著名的Macrohard的软件World来写他的文章. 不幸的是,这个软件相当不稳定,它总是崩溃. DRD需要在他的文章 ...
- 线路由器频段带宽是是20M好还是40M好
无线路由器频段带宽还是40M好. 40M的信号强,速度快. 1.20MHz在11n的情况下能达到144Mbps带宽.穿透性不错.传输距离较远 40MHz在11n的情况下能达到300Mbps带宽.穿 ...
- stm32学习笔记之GPIO功能框图分析
GPIO 是通用输入输出端口的简称,简单来说就是STM32 可控制的引脚,STM32 芯片的GPIO 引脚与外部设备连接起来,从而实现与外部通讯.控制以及数据采集的功能.STM32 芯片的GPIO被分 ...
- [CSP-S2021] 廊桥分配
链接: P7913 题意: 有 \(m_1\) 架飞机和 \(m_2\) 架飞机停在两个机场,每架飞机有到达和离开的时间,要将 \(n\) 个廊桥分给两个机场,每个廊桥同一时刻只能停一架飞机,需要最大 ...
- iptables 原理及应用
转自:iptables 原理及应用 iptables是一个Linux下优秀的nat+防火墙工具,我使用该工具以较低配置的传统pc配置了一个灵活强劲的防火墙+nat系统,小有心得,看了网上也有很多这方面 ...
- JAVA笔记10__Math类、Random类、Arrays类/日期操作类/对象比较器/对象的克隆/二叉树
/** * Math类.Random类.Arrays类:具体查JAVA手册...... */ public class Main { public static void main(String[] ...
- 安装配置多个版本JDK
前言:JDK有多个版本,有时为了开发需要切换不同的版本,在一部电脑上安装多个JDK,只需要按以下配置,每次即可轻松使用.以下环境为Windows10 安装JDK 安装JDK8 配置环境变量 需要配置J ...
- 谷歌chrome多个相同用户登陆同一个机器多开配置
创建快捷方式,目标中填写:路径+参数如下所示即可 参数:--user-data-dir=%LOCALAPPDATA%\Google\Chrome\%SessionName%
- 小白都能看懂的Spring源码揭秘之IOC容器源码分析
目录 前言 IOC 只是一个 Map 集合 IOC 三大核心接口 IOC 初始化三大步骤 定位 加载 注册 总结 前言 在 Spring 框架中,大家耳熟能详的无非就是 IOC,DI,Spring M ...
- 匿名函数托管器 spring-boot-func-starter
spring-boot-func-starter spring-boot-func-starter 介绍 项目地址: https://gitee.com/yiur/spring-boot-func-s ...