背景:最近在做一个功能改造,老系统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万条数据方案相关推荐

  1. 罗永浩:锤子手机一共卖了12万部(但计划50万)……我已经交出微博密码……(老罗想通了:-))...

    前段时间有个新闻标题:老罗的情怀只值1000块 ~是针对锤子手机降价的事,不过,看到36kr这篇文章,看来老罗想明白了~ 今天下午两点半,罗永浩在北京发布了可能是最后一期"一个理想主义者的创 ...

  2. PHP大数据量(大于50万)导出到Excel解决方案

    综述 最近在工作中遇到这样一个问题,公司项目要求订单有导出功能,以前虽然也使用PHPExcel做过几个导出功能,但是这次所需导出的数量巨大,因此在开发中遇到一些导出的坑,在此进行总结记录一下. 吐槽 ...

  3. oracle数据泵导出 不全,Oracle RAC数据泵导出问题处理

    1. 设置导出文件路径 sqlplus / as sysdba SQL> alter session set container=spdb1pdb; SQL> create directo ...

  4. oracle数据泵导出多表,oracle 数据泵导出表

    oracle 数据泵导出演示步骤 1.使用 oracle 用户创建目录 mkdir software_bak [oracle@master ~]$ cd software_bak/ [oracle@m ...

  5. php年薪50万,为什么那么多年薪50万的人,都不买奔驰宝马,反而买十几万的车?...

    如今我国人们的生活条件都有了普遍的提高,告别了吃不饱穿不暖的年代之后,吃喝等方面的追求显然已经满足不了人们的需求,越来越多的人开始着眼于提高生活的质量.而对于很多普通人来说,买一辆经济型的家用车或是他 ...

  6. 导出一条数据_来自小师弟的灵魂拷问之数据泵导出丢失的那些数据量去哪了?...

    在精彩刺激又些许无聊的运维生活中,有可爱呆萌的师弟师妹,也是为工作增添了一些色彩.正在午休的时候, 尚未毕业的小师弟在悄悄问小师妹,为什么数据库中查出来的数据量有100G,expdp导出的dump文件 ...

  7. eclipse.jsp文件放哪_来自小师弟的灵魂拷问之数据泵导出丢失的那些数据量去哪了?...

    在精彩刺激又些许无聊的运维生活中,有可爱呆萌的师弟师妹,也是为工作增添了一些色彩.正在午休的时候, 尚未毕业的小师弟在悄悄问小师妹,为什么数据库中查出来的数据量有100G,expdp导出的dump文件 ...

  8. Java实现Excel导入数据库,数据库中的数据导入到Excel

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. 实现的功能: Java实现Excel导入数据库,如果存在就更新 数据库中的数据导入到Excel 1. ...

  9. cfdpost导出图片_CFD-POST出数据方法.pdf

    CFD-POST出数据方法 CFD-PSOT导出数据方法 说明:本次教程包含两方面内容,导出一点的数据和导出点云的 数据 (有时候在模拟过程中,需要得到一个平面的速度.压力.温度 分布情况,可以在平面 ...

最新文章

  1. C# 获取USB设备信息
  2. CodeForces 474.D Flowers
  3. Spark _22 _创建DataFrame的几种方式(一)
  4. Semantic-UI的React实现(二):CSS类构造模块 1
  5. android 面试总结,后续注意学习
  6. sqllite java 密码,SQLite登录检查用户名和密码
  7. mysql where true_在MySQL中选择查询,检查字符串或在where子句中检查是否为true?
  8. 搜索的近义词php,挖掘关键词同义的近义词提高排名
  9. 小白做淘客店铺新玩法
  10. python 提取字幕_使用Python从zimuku下载字幕
  11. 地震了,地震了!!!
  12. 让连续的英文或数字自动换行
  13. 《Redis开发与运维》阅读笔记:键管理之单个键管理
  14. 移动机器人传感器——GNSS
  15. 《斯坦福极简经济学》读书笔记
  16. 短距离无线通讯-蓝牙
  17. 讯飞输入法键盘计算机,讯飞输入法电脑版使用教程
  18. 《奔跑吧Linux内核(第二版)》第三章笔记
  19. php 固定长度加密解密,如何加密/解密数据在PHP?
  20. Rasa Core实践 报时机器人

热门文章

  1. window 相关dll文件下载
  2. 12、FPGA程序的固化和下载
  3. sql:当一列为空时取另一列(case when then)
  4. spring boot 项目打包时报错 Execution default of goal org.springframework.boot:spring-boot-maven-plugin
  5. 带你了解CPU的世界
  6. qq音信点亮最全说明
  7. 什么是静态网站?什么是动态网站?
  8. linux qt地图开发教程,基于QT的电子地图的设计与实现
  9. Vmware虚拟机下三种网络模式配置
  10. CommMonitor监控串口数据