姓名:游海波
学号:20181213863
学院:广研院
原文链接:https://mp.weixin.qq.com/s/L9KatJLLIozYBRQKQwyNTA
【嵌牛导读】导出是后台管理系统的常用功能,当数据量特别大的时候会内存溢出和卡顿页面。
【嵌牛鼻子】Java,sql,EasyExcel
【嵌牛提问】如何解决几百万数据量的Excel导出会内存溢出和卡顿问题?
【嵌牛正文】
一、简介
导出是后台管理系统的常用功能,当数据量特别大的时候会内存溢出和卡顿页面,曾经自己封装过一个导出,采用了分批查询数据来避免内存溢出和使用SXSSFWorkbook方式缓存数据到文件上以解决下载大文件EXCEL卡死页面的问题。
不过一是存在封装不太友好使用不方便的问题,二是这些poi的操作方式仍然存在内存占用过大的问题,三是存在空循环和整除的时候数据有缺陷的问题,以及存在内存溢出的隐患。
无意间查询到阿里开源的EasyExcel框架,发现可以将解析的EXCEL的内存占用控制在KB级别,并且绝对不会内存溢出(内部实现待研究),还有就是速度极快,大概100W条记录,十几个字段,只需要70秒即可完成下载。
遂抛弃自己封装的,转战研究阿里开源的EasyExcel. 不过 说实话,当时自己封装的那个还是有些技术含量的,例如 外观模式,模板方法模式,以及委托思想,组合思想,可以看看。
EasyExcel的github地址是:https://github.com/alibaba/easyexcel
二、案例
2.1 POM依赖
2.2 POJO对象
2.3 测试环境
2.3.1.数据量少的(20W以内吧):一个SHEET一次查询导出
2.3.2.数据量适中(100W以内):一个SHEET分批查询导出
2.3.3.数据量很大(几百万都行):多个SHEET分批查询导出
2.4 生产环境
2.4.0.Excel常量类
2.4.1.数据量少的(20W以内吧):一个SHEET一次查询导出
2.4.2.数据量适中(100W以内):一个SHEET分批查询导出
2.4.3.数据里很大(几百万都行):多个SHEET分批查询导出
三、总结
造的假数据,100W条记录,18个字段,测试导出是70s。在实际上产环境使用的时候,具体的还是要看自己写的sql的性能。sql性能快的话,会很快。
有一点推荐一下:在做分页的时候使用单表查询, 对于所需要处理的外键对应的冗余字段,在外面一次性查出来放到map里面(推荐使用@MapKey注解),然后遍历list的时候根据外键从map中获取对应的名称。