那些年我们爬过的山 - mybatis批量导入
【原创作品,转载请注明出处】
写这篇文章之前想着给这篇博客起一个文艺一点的标题,思来想去,想到了那些年我们爬过的山,或者我们一起趟过的河?代码不规范,同事两行泪,这是多么痛的领悟啊!
背景
本组一名实习生,由于学校有事情需要回去处理,我便将他的代码接管过来,正好赶上本次迭代上线,需要将同事的代码提交测试,如果被测试出来有bug,我就来负责bug修复,代码优化等。由于不同的开发人员都有自己的编程习惯,所以不同人员所写的代码多少都会有些差异,比如:变量的命名、代码的格式等,即使组内有一套开发规范也还是会出现一些差异,这就是所谓的个性?特点? 当然 特点只是特点,并不能称得上个性。既然风格不同,那么看别人代码的时候会有值得学习的地方,也有自己感觉不舒服的地方。也罢,毕竟人都有“个性”。
问题现象
这次我接手同事的代码主要是一个Excel导入数据库这样一个功能,在测试人员测试导入数据的时候,使用的导入数据有2w条作为测试数据导入数据库,现象是 导入后发现页面先是显示上传中,之后页面没有任何反馈,经排查后发现是因为后台还在处理导入数据逻辑,时间过长页面没有得到反馈,导致页面超时。
排查过程
- 接着查看了导入逻辑,发现导入的时候,使用的是将2w条数据循环导入数据库,每一次导入都会进行数据库交互,导致数据库连接池的连接被耗尽,会再次进行创建、分配、释放等操作,从而导致之后的处理变得缓慢。
- 基于这些考虑使用了批量导入,批量导入的目的就是一次导入多条数据,减少和数据库交互次数,减轻数据库压力。
- 修改程序后测试导入所用的时间并不理想,继续排查发现 在导入前还有判断卡密是否存在数据库 这样一个操作,和循环插入没有什么区别,也是会循环2w次数据库查询。因此首先想到的是减少和数据库的交互次数,先把数据查询出来,放到内存中,再将两个集合进行比较,发现数据量小的时候还可以,数据量大了就会很缓慢,尝试了几个网上搜到的“高效”list去重,发现效果并不明显。
- 遂继续找其他的方法,最后找到使用MySQL的ignore关键字【作用:若有导致unique key 冲突的记录,则该条记录不会被插入到数据库中,去重字段一定要是唯一索引】就可以解决判断卡密重复的问题,** 经过测试 导入2w条数据由原来的16分钟,减少到目前的10秒 左右** 。
总结
对于本次问题的排查,可以总结为问题发现,和问题排查。发现问题时首先要快速了解该功能的主要逻辑是什么,这次的导入主要有两点,一是 导入前判断是否有和数据库重复,二是导入操作。弄明白主要逻辑之后,就要分析,导入慢肯定是这两个逻辑的某一个逻辑慢,或者是两个逻辑都慢。经过分析发现,这两个逻辑都出现了循环建立数据库连接的问题,发现了问题的根本原因后,就要减少建立数据库连接次数,问题便得到解决。
主要代码
对于导入前和数据库判断是否有重复的,使用了mysql的一个关键字ignore,关键字的作用是:若有导致unique key 冲突的记录,则该条记录不会被插入到数据库中,去重字段一定要是唯一索引。其他就是拼接SQL使用批量导入。下面将主要的代码贴出来供大家参考。
- 批量导入时每次批量插入100条数据,这样数据库连接建立的次数就从原来的 20000次减少到200次。
// 批量入库,每次批量插入100条
List<Detail> detailList = new ArrayList<>();
List<List<Detail>> tempList = new ArrayList<>();
int insertCount = 100;
for (int i = 0; i < detailList.size(); i += insertCount) {
if ((i + insertCount) < detailList.size()) {
List<Detail> newList = new ArrayList<>();
newList.addAll(detailList.subList(i, i + insertCount));
tempList.add(newList);
} else {
List<Detail> newList = new ArrayList<>();
newList.addAll(detailList.subList(i, detailList.size()));
tempList.add(newList);
}
}
Map<String, Object> map = detailManager.batchInsertDetail(tempList);
- mybatis的写法
<insert id="batchInsertDetail" parameterType="java.util.List">
insert ignore into my_table
(id,code,status)
values
<foreach collection ="list" item="detail" index= "index" separator =",">
(#{detail.id,jdbcType=BIGINT},#{detail.code,jdbcType=VARCHAR},#{detail.status,jdbcType=TINYINT})
</foreach >
</insert>
那些年我们爬过的山 - mybatis批量导入的更多相关文章
- Springboot+Mybatis批量导入多条数据
在Mapper.xml最下面填写 <!-- 批量插入生成的兑换码 --> <insert id ="insertCodeBatch" parameterType= ...
- mybatis 批量导入数据到mysql返回批量Id
1.首先mybatis版本必需是3.3.1或以上 2.mapper配置文件中 <insert id="insertOrderBatch" parameterType=&quo ...
- Mybatis框架进行批量导入和删除有三种方式
首先创建一个数据库 CREATE TABLE user ( id varchar(32) CHARACTER SET utf8 NOT NULL, name varchar(50) CHARA ...
- 订餐系统之Excel批量导入
批量导入现在基本已经成为各类系统的标配了,当前,我们订餐系统也不例外,什么商家呀.商品呀.优惠码之类的,都少不了.毕竟嘛,对非开发人员来说,看到Excel肯定比看到很多管理系统还是要亲切很多的.这里, ...
- java实现文件批量导入导出实例(兼容xls,xlsx)
1.介绍 java实现文件的导入导出数据库,目前在大部分系统中是比较常见的功能了,今天写个小demo来理解其原理,没接触过的同学也可以看看参考下. 目前我所接触过的导入导出技术主要有POI和iRepo ...
- mybatis批量增加与删除——(十五)
1.首先应该明白,mybatis增删改返回值是int型的影响行数的值 mapper接口 package cn.xm.mapper; import java.util.List; import cn.x ...
- 对大数据的批量导入MySQL数据库
自己的库里有索引在用insert导入数据时会变慢很多 使用事务+批量导入 可以配置使用spring+mybatis整合的方式关闭自动提交事务(地址),选择批量导入每一百条导入使用list存储值传入到m ...
- es批量导入进一对多的数据
es批量导入进一对多的数据 我有一个产品表 一个产品对应多个属性名 一个属性名对应多个属性值 一个产品还对应一个分类名称 控制层 @ApiOperation(value = "导入所有 ...
- AWVS批量导入网站(刷漏洞入门)
今天整了一天这个AWVS批量扫描脚本,主要是下了好几个版本的AWVS,都不稳定,一次次删除又一次次安装. 做这件事儿目的就是为了批量刷漏洞,不过弄好之后又不打算刷漏洞了,不太喜欢无脑刷漏洞,没什么意义 ...
随机推荐
- Linux下压缩文件-1
tar负责打包,gzip负责压缩 tar-c: 建立压缩档案-x:解压-t:查看内容-r:向压缩归档文件末尾追加文件-u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的 ...
- 20155201 2016-2017-2 《Java程序设计》第六周学习总结
20155201 2016-2017-2 <Java程序设计>第六周学习总结 教材学习内容总结 第十章 输入/输出 字节输入类: Java将输入/输出抽象化为串流,数据有来源及目的地,衔接 ...
- 【Linux 命令】iftop安装与简单使用
iftop是linux下的一个流量监控工具,用于查看实时网络流量,反向解析IP,显示端口信息官网:http://www.ex-parrot.com/~pdw/iftop/ 1.安装必须软件包 yum ...
- HDU 1427 速算24点 (深搜)
题目链接 Problem Description 速算24点相信绝大多数人都玩过.就是随机给你四张牌,包括A(1),2,3,4,5,6,7,8,9,10,J(11),Q(12),K(13).要求只用' ...
- JS模块规范
ES6标准发布后,module成为标准,标准的使用是以export指令导出接口,以import引入模块,但是在我们一贯的node模块中,我们采用的是CommonJS规范,使用require引入模块,使 ...
- C++ Primer 5th 第18章 用于大型程序的工具
C++大规模程序设计至少存在三个特殊要求: 错误处理 库的引入 复杂建模 以上三种对应C++语言的三种特性:异常处理.命名空间.多重继承. 异常处理 异常处理机制是一种允许偷懒的工具,在出现非正确的情 ...
- 【划水闲谈】Terraria 1.3.5更新
我知道这本应是一个算法博客,但又有谁规定了不能发点其他内容呢? Terraria,一个有趣的沙盒游戏.在这里,你可以建造,挖掘,开始一次又一次新的冒险. 4月19日,Re-Logic承诺的官方中文版终 ...
- MySQL分布式集群之MyCAT(二)【转】
在第一部分,有简单的介绍MyCAT的搭建和配置文件的基本情况,这一篇详细介绍schema的一些具体参数,以及实际作用 首先贴上自己测试用的schema文件,双引号之前的反斜杠不会消除,姑 ...
- Serv-U 的升级及数据备份和迁移【转】
Serv-U 配置备份 在serv-u7.x及以上版本安装目录下,有一个文件Serv-U.Archive是serv-u的配置文件,有一个users文件夹是Serv-U的域和用户的信息,那么我们只需 ...
- linux cpu、内存、硬盘空间查询
[CPU] 算式: CPU总核数 = 物理CPU个数 * 每颗物理CPU的核数 总逻辑CPU数 = 物理CPU个数 * 每颗物理CPU的核数 * 超线程数 #查看CPU型号 cat /proc/cpu ...