Excel导入30万条数据和导出50万条数据方案
背景:最近在做一个功能改造,老系统Excel导入导出大批量数据,要求支持一次性导入30万条数据,一次性导出50万条数据,还需要对数据进行校验,另外对性能有要求,不能比老系统的性能差。和业务了解了老系统导入30万的数据耗时为10分钟左右,导出50万数据耗时1分钟左右。
说实话刚开始了解需求的时候有点慌,之前没有做过这么大批量数据的导入导出,因为这是跳槽进公司的第一个需求,怕做不好得滚蛋。
-------------------------------------------分割线-------------------------------------------
项目技术栈:Springboot + Mybatis + Oracle + Redis + Apollo
家里的电脑配置,以下部分测试是使用家里的电脑进行:CPU:I5-7500 RAM:8G 硬盘:固态硬盘
一、导入Excel问题汇总及解决方案:
1、内存溢出、读取文件性能太差(和电脑的配置有关)
a) 使用POI工具的常规读取Excel文件方式导致内存溢出
POI读取Excel文件代码:
FileInputStream in = new FileInputStream(file);Workbook wk = new XSSFWorkbook(in);
测试的Excel文件大小为:12M,53万条数据
代码测试结果:
CPU和RAM资源被占用90%以上
Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
2、解决方案
使用别人封装的工具
<dependency><groupId>com.monitorjbl</groupId><artifactId>xlsx-streamer</artifactId><version>2.0.0</version></dependency>
读取Excel文件代码:
FileInputStream in = new FileInputStream(file);Workbook wk = StreamingReader.builder().rowCacheSize(500).bufferSize(2048).open(in);
代码测试结果:
CPU和RAM资源占用分别为 40%、70%
2022-05-05 23:30:25.067[1651764625067] | INFO | main | ExcelImportTask - Excel文件大小12M,共530328条数据,解析Excel文件耗时13秒
3、校验数据是否已经存在数据库中
主要校验导入文件中的三个唯一主键字段在数据库中是否存在,刚开始以为是主键的原因,查数据库校验会很快,所以使用循环遍历和组装in条件去和数据库查重,但是几十万的数据量就需要和数据库交互上万甚至上几十万次,因此性能是非常之差。
不可行的方案:
3.1、循环遍历查重
3.2、每1000条组装一次in条件查询(in条件Oracle最多支持1000个)
3.3、使用多线程的方式查重(没试过,但是觉得不行,就算是多线程成也需要与数据库上万次交互)
3.4、使用redis,表数据个月都会新增几十上百万的数据,所以使用缓存的方式也不可行
解决方案:临时表
使用临时表,创建一张临时表,把导入的数据先插入临时表,然后再使用主表和临时表进行查重,查重结束后删除临时表数据。
测试结果(使用公司电脑测试):
1、导入30万数据,存在100条重复数据,查重校验耗时是1秒左右
2、同一批30万的数据,导入两次,重复数据为30万条,查重校验耗时大约30秒
4、大批量数据插入数据库性能
mybatis-plus有批量插入的API:saveBatch,每1000条插入一次数据库,经过测试插入30万条数据耗时大约再180-200秒左右,觉得性能太差,改用了原生JDBC的批量插入,经过测试插入30万条数据大约3-4秒
总结:
1、在导入数据量太大的情况下不能使用普通POI读取方式,因为会导致内存溢出,服务器资源被大量占用,读取性能巨差
2、需要与数据库查重不可频繁查询数据库,可使用临时表方案
3、批量插入可以使用原生JDBC批量插入
4、经过一系列优化,导入30万条数据整个任务耗时大约60秒,比老系统的导入性能提升了10倍
二、导出问题汇总及解决方案:
导出数据主要的性能瓶颈主要是在查询数据库的步骤,刚开始使用mybatis的方式分页查询,但是查询50万条数据需要耗时180秒左右,比老系统性能差3倍,不可行。
最后使用原生JDBC的方式查询,查询50万条数据大约耗时30-40秒左右
整个导出任务耗时大约60秒。
读取Excel大文件参考博客:poi 上传Excel如何处理大文件,避免内存溢出_小何开发的博客-CSDN博客_poi大文件导入内存溢出
结语:导入30万数据经过一些列优化,耗时约60秒,比老系统提升了10倍,导出耗时约60秒,和老系统持平。
Excel导入30万条数据和导出50万条数据方案相关推荐
- 罗永浩:锤子手机一共卖了12万部(但计划50万)……我已经交出微博密码……(老罗想通了:-))...
前段时间有个新闻标题:老罗的情怀只值1000块 ~是针对锤子手机降价的事,不过,看到36kr这篇文章,看来老罗想明白了~ 今天下午两点半,罗永浩在北京发布了可能是最后一期"一个理想主义者的创 ...
- PHP大数据量(大于50万)导出到Excel解决方案
综述 最近在工作中遇到这样一个问题,公司项目要求订单有导出功能,以前虽然也使用PHPExcel做过几个导出功能,但是这次所需导出的数量巨大,因此在开发中遇到一些导出的坑,在此进行总结记录一下. 吐槽 ...
- oracle数据泵导出 不全,Oracle RAC数据泵导出问题处理
1. 设置导出文件路径 sqlplus / as sysdba SQL> alter session set container=spdb1pdb; SQL> create directo ...
- oracle数据泵导出多表,oracle 数据泵导出表
oracle 数据泵导出演示步骤 1.使用 oracle 用户创建目录 mkdir software_bak [oracle@master ~]$ cd software_bak/ [oracle@m ...
- php年薪50万,为什么那么多年薪50万的人,都不买奔驰宝马,反而买十几万的车?...
如今我国人们的生活条件都有了普遍的提高,告别了吃不饱穿不暖的年代之后,吃喝等方面的追求显然已经满足不了人们的需求,越来越多的人开始着眼于提高生活的质量.而对于很多普通人来说,买一辆经济型的家用车或是他 ...
- 导出一条数据_来自小师弟的灵魂拷问之数据泵导出丢失的那些数据量去哪了?...
在精彩刺激又些许无聊的运维生活中,有可爱呆萌的师弟师妹,也是为工作增添了一些色彩.正在午休的时候, 尚未毕业的小师弟在悄悄问小师妹,为什么数据库中查出来的数据量有100G,expdp导出的dump文件 ...
- eclipse.jsp文件放哪_来自小师弟的灵魂拷问之数据泵导出丢失的那些数据量去哪了?...
在精彩刺激又些许无聊的运维生活中,有可爱呆萌的师弟师妹,也是为工作增添了一些色彩.正在午休的时候, 尚未毕业的小师弟在悄悄问小师妹,为什么数据库中查出来的数据量有100G,expdp导出的dump文件 ...
- Java实现Excel导入数据库,数据库中的数据导入到Excel
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. 实现的功能: Java实现Excel导入数据库,如果存在就更新 数据库中的数据导入到Excel 1. ...
- cfdpost导出图片_CFD-POST出数据方法.pdf
CFD-POST出数据方法 CFD-PSOT导出数据方法 说明:本次教程包含两方面内容,导出一点的数据和导出点云的 数据 (有时候在模拟过程中,需要得到一个平面的速度.压力.温度 分布情况,可以在平面 ...
最新文章
- C# 获取USB设备信息
- CodeForces 474.D Flowers
- Spark _22 _创建DataFrame的几种方式(一)
- Semantic-UI的React实现(二):CSS类构造模块 1
- android 面试总结,后续注意学习
- sqllite java 密码,SQLite登录检查用户名和密码
- mysql where true_在MySQL中选择查询,检查字符串或在where子句中检查是否为true?
- 搜索的近义词php,挖掘关键词同义的近义词提高排名
- 小白做淘客店铺新玩法
- python 提取字幕_使用Python从zimuku下载字幕
- 地震了,地震了!!!
- 让连续的英文或数字自动换行
- 《Redis开发与运维》阅读笔记:键管理之单个键管理
- 移动机器人传感器——GNSS
- 《斯坦福极简经济学》读书笔记
- 短距离无线通讯-蓝牙
- 讯飞输入法键盘计算机,讯飞输入法电脑版使用教程
- 《奔跑吧Linux内核(第二版)》第三章笔记
- php 固定长度加密解密,如何加密/解密数据在PHP?
- Rasa Core实践 报时机器人