百万数据的导入导出解决方案

简介: 百万数据的导入导出解决方案

前言

因为在工作中遇到了大数据的导入和导出,问题既然来了逃跑不如干掉它!!!

只要这一次解决了,后期遇到同样的问题就好解决了。

废话不多说,开始撸起来!!!


一、传统POI的的版本优缺点比较?

HSSFWorkbook

它是POI版本中最常用的方式,不过:

  • 它的缺点是 最多只能导出 65535行,也就是导出的数据函数超过这个数据就会报错;
  • 它的优点是 不会报内存溢出。(因为数据量还不到7w所以内存一般都够用,首先你得明确知道这种方式是将数据先读取到内存中,然后再操作)

XSSFWorkbook

  • 优点:这种形式的出现是为了突破HSSFWorkbook的65535行局限,是为了针对Excel2007版本的1048576行,16384列,最多可以导出104w条数据;
  • 缺点:伴随的问题来了,虽然导出数据行数增加了好多倍,但是随之而来的内存溢出问题也成了噩梦。因为你所创建的book,Sheet,row,cell等在写入到Excel之前,都是存放在内存中的(这还没有算Excel的一些样式格式等等),可想而知,内存不溢出就有点不科学了!!

SXSSFWorkbook

从POI 3.8版本开始,提供了一种基于XSSF的低内存占用的SXSSF方式:

优点:

  • 这种方式不会一般不会出现内存溢出(它使用了硬盘来换取内存空间,
  • 也就是当内存中数据达到一定程度这些数据会被持久化到硬盘中存储起来,而内存中存的都是最新的数据),
  • 并且支持大型Excel文件的创建(存储百万条数据绰绰有余)。

缺点:

  • 既然一部分数据持久化到了硬盘中,且不能被查看和访问那么就会导致,
  • 在同一时间点我们只能访问一定数量的数据,也就是内存中存储的数据;
  • sheet.clone()方法将不再支持,还是因为持久化的原因;
  • 不再支持对公式的求值,还是因为持久化的原因,在硬盘中的数据没法读取到内存中进行计算;
  • 在使用模板方式下载数据的时候,不能改动表头,还是因为持久化的问题,写到了硬盘里就不能改变了

二、正菜

1.想要解决问题我们首先要明白自己遇到的问题是什么?

  1. 我遇到的数据量超级大,使用传统的POI方式来完成导入导出很明显会内存溢出,并且效率会非常低;
  2. 数据量大直接使用select * from tableName肯定不行,一下子查出来300w条数据肯定会很慢;
  3. 300w 数据导出到Excel时肯定不能都写在一个Sheet中,这样效率会非常低;估计打开都得几分钟;
  4. 300w数据导出到Excel中肯定不能一行一行的导出到Excel中。频繁IO操作绝对不行;
  5. 导入时300万数据存储到DB如果循环一条条插入也肯定不行
  6. 导入时300w数据如果使用Mybatis的批量插入肯定不行,因为Mybatis的批量插入其实就是SQL的循环;一样很慢。

解决思路

  • 针对1 :其实问题所在就是内存溢出,我们只要使用对上面介绍的POI方式即可,主要问题就是原生的POI解决起来相当麻烦。
    经过查阅资料翻看到阿里的一款POI封装工具EasyExcel,上面问题等到解决;
  • 针对2:不能一次性查询出全部数据,我们可以分批进行查询,只不过时多查询几次的问题,况且市面上分页插件很多。此问题好解决。
  • 针对3:可以将300w条数据写到不同的Sheet中,每一个Sheet写一百万即可。
  • 针对4:不能一行一行的写入到Excel上,我们可以将分批查询的数据分批写入到Excel中。
  • 针对5:导入到DB时我们可以将Excel中读取的数据存储到集合中,到了一定数量,直接批量插入到DB中。
  • 针对6:不能使用Mybatis的批量插入,我们可以使用JDBC的批量插入,配合事务来完成批量插入到DB。即
    Excel读取分批+JDBC分批插入+事务。

300w数据的导出解决思路

代码如下(示例):

  • 首先在查询数据库层面,需要分批进行查询(我使用的是每次查询20w)
  • 每查询一次结束,就使用EasyExcel工具将这些数据写入一次;
  • 当一个Sheet写满了100w条数据,开始将查询的数据写入到另一个Sheet中;
  • 如此循环直到数据全部导出到Excel完毕。

300w的数据导出时间用时大概:2分15秒

300w数据导入

代码不重要首先还是思路

  1. 首先是分批读取读取Excel中的300w数据,这一点EasyExcel有自己的解决方案,我们可以参考Demo即可,只需要把它分批的参数3000调大即可。我是用的20w;(一会儿代码一看就能明白)
  2. 其次就是往DB里插入,怎么去插入这20w条数据,当然不能一条一条的循环,应该批量插入这20w条数据,同样也不能使用Mybatis的批量插入语,因为效率也低。可以参考下面链接【Myabtis批量插入和JDBC批量插入性能对比】
  3. 使用JDBC+事务的批量操作将数据插入到数据库。(分批读取+JDBC分批插入+手动事务控制)

EasyExcel分批读取300W数据只用了 82.886秒
使用JDBC分批+事务操作插入300w条数据综合只用时 8.209秒


总结

这次工作中遇到的问题也给我留下了深刻印象,同时也是我职业生涯添彩的一笔。

最起码简历上可以写上你处理过上百万条数据的导入导出。

目录
相关文章
|
JSON Linux 网络安全
一文搞定:whois数据库查询域名信息(WHOIS)
一文搞定:whois数据库查询域名信息(WHOIS)
4810 0
一文搞定:whois数据库查询域名信息(WHOIS)
|
前端开发 Java 关系型数据库
【SpringBoot】微服务学习笔记七:微服务中异步调用数据提交数据库的问题
【SpringBoot】微服务学习笔记七:微服务中异步调用数据提交数据库的问题
952 0
【SpringBoot】微服务学习笔记七:微服务中异步调用数据提交数据库的问题
|
机器学习/深度学习
小尺度信道建模 | 带你读《大规模天线波束赋形技术原理与设计 》之二十六
小尺度衰落是指无线电信号在短时间或短距离(若干波长)传播后其幅度、 相位或多径时延的快速变化。这种衰落是由于同一传输信号沿不同的路径传播, 由不同时刻(或相位)到达接收机的信号互相叠加所引起的,这些不同路径到 达的信号称为多径信号,接收机的信号强度取决于多径信号的强度、相对到达 时延以及传输信号的带宽。
10345 1
 小尺度信道建模  | 带你读《大规模天线波束赋形技术原理与设计 》之二十六
|
5月前
|
存储 供应链 JavaScript
ERP系统生产管理全流程解析
ERP系统为企业提供集成化生产管理解决方案,涵盖从销售预测、主生产计划、物料需求计划到生产订单下达、过程控制及成品入库的全流程。通过规范生产流程,提升计划准确性与执行效率,实现资源优化配置。实施时需注重前期规划、员工培训、数据管理及持续优化,确保系统有效支撑企业生产运营。
380 3
|
存储 NoSQL Redis
2)Redis 的键值对长什么样子,又是怎么存储的?
2)Redis 的键值对长什么样子,又是怎么存储的?
346 0
|
Java easyexcel 大数据
震撼!通过双重异步,Excel 10万行数据导入从191秒优化到2秒!
通过合理设计线程池和利用异步编程模型,本文展示了如何将 Excel 10万行数据的导入时间从191秒优化到2秒。文章详细介绍了使用 Spring Boot 的 `@Async` 注解、自定义线程池和 EasyExcel 进行大数据量的 Excel 解析和异步写入数据库的方法。通过分而治之的策略,减少了系统的响应时间,提高了并发处理能力。同时,还分析了如何根据 CPU 和 IO 密集型任务的特性,合理设置线程池的参数,以充分发挥硬件资源的性能。
|
存储 Java easyexcel
招行面试:100万级别数据的Excel,如何秒级导入到数据库?
本文由40岁老架构师尼恩撰写,分享了应对招商银行Java后端面试绝命12题的经验。文章详细介绍了如何通过系统化准备,在面试中展示强大的技术实力。针对百万级数据的Excel导入难题,尼恩推荐使用阿里巴巴开源的EasyExcel框架,并结合高性能分片读取、Disruptor队列缓冲和高并发批量写入的架构方案,实现高效的数据处理。此外,文章还提供了完整的代码示例和配置说明,帮助读者快速掌握相关技能。建议读者参考《尼恩Java面试宝典PDF》进行系统化刷题,提升面试竞争力。关注公众号【技术自由圈】可获取更多技术资源和指导。
|
前端开发 fastjson
使用map传参,解决后台没有前台对应实体的类的情况
使用map传参,解决后台没有前台对应实体的类的情况
250 0
|
监控 算法 数据可视化
ERP系统中的生产调度与计划排程解析
【7月更文挑战第25天】 ERP系统中的生产调度与计划排程解析
868 1
|
SQL Java 数据库连接
Hibernate 批量操作来袭!掌握最佳实践,轻松应对数据洪流,开启高效开发新时代
【9月更文挑战第3天】在软件开发中,高效数据操作至关重要。作为流行的Java持久化框架,Hibernate提供了强大的数据库操作功能。本文探讨了Hibernate批量操作,包括批量插入、更新和删除的最佳实践,通过使用原生SQL和`Session`的`createNativeQuery()`方法,结合`addBatch()`及`executeBatch()`方法实现高效批量操作。合理设置批量大小、事务管理和性能测试是优化的关键。在实际开发中,应根据业务需求和性能要求选择合适的方法,以提升程序性能和可维护性。
962 3

热门文章

最新文章