Java如何导出大批量的数据

我们平台最近有个需求需要查询每天的业务日志,然后也有导出功能。每天业务量数据很大。每天都好几千万的数据。
然后页面有个查询功能还有导出的功能。这个导出功能不知道是什么时候写的了,反正就一直有。我尝试用导出,然后就是网络访问压力会很大,同时也有内存溢出的问题。
那么问题来了,如何对这种千万级别的数据导出到Excel中进行优化呢?或者有没有好一点的方法进行导出呢?慢一些无所谓,只要不会把整个程序拖卡就行。

1 个赞

多线程检索到磁盘,再合并响应给客户端。
例如有1千万数据,用10个线程根据ID分段检索到磁盘。最后合并成一个文件。最后响应给客户端。

哥哥上代码学习下

1 个赞

你现在用的是什么导出POI?建议用EasyExcel,我之前优化有奇效,可以试试

mysql推荐是表500w数据量比较好,千万级别,像业务日志这种推荐上es。

现在就是很普通的那种,查完然后POI导出,这个功能之前写的就有问题,导出没有条件设置,直接报内存溢出了。EasyExcel能导出千万级的数据吗????

上es估计不太行。我们这他不让加新的,只让动代码去优化… …

ES替换没有什么痕迹,之前我就是因为POI数据量过大导致OOM,替换完ES完美解决,从26s>8s

1 个赞

生产上都没安这玩意儿 :joy:我倒是也想用啊。生产想装个东西都需要各种审核各种评测才可以。

首先你这日志存哪里呀?文件系统还是数据库表,还是 NoSQL,存的位置不一样处理方式不一样。

另外你的数据结构是怎么样的,是简单的数据结构,还是复杂结构,字段是不是很多。

假设你数据就在数据库中,查询的结果返回多少的数据?如果就返回几万,可以考虑转换为 CSV 文件,CSV 文件 Excel 是可以打开的,而且 Excel 也有打开限制,记录太多了 Excel 也会被拖死。

日志是存在数据库里的。字段也很多,包括什么日期,内容,流水号等等。现在就是简单的POI导出到Excel中的。CSV文件虽然也可以,但是这个需求是我们公司业务人员使用的。CSV文件他们不方便使用。最好就还是Excel文件。 数据量比较大,目前看他不设置条件的,最少几千万。我目前的想法是不让他们导出这么多的数据。但是这个还得和产品商量才可以。但是预防万一,有些业务不讲理,人就会说我就想全要。所以我还是得找到如何将这么大量的数据进行导出的方法。

针对你现在的数据库,千万级别的,不管采取什么方案,什么 POI 工具在线导出方案都会超时。

原因有:

  1. 数据处理时间会很长,生成的文件会很大,网络传输回来肯定会超时。
  2. 其次 Excel 建议的数据量一般是不超过 5 万,全部导入到一个文件中,客户的电脑是根本打不开的,Excel 早就会被拖死了。这样的数据给你们业务毫无意义。就算勉强打开了, Excel 的搜索功能根本用不了。
  3. 你这还是一个用户导出的情况,如果 10 个用户同时导出,你试试看?

所以,你需要和业务商量你们到底要这些数据干什么。但是放一个文件中肯定是没有任何意义的。

正常来说针对这种数据量的通常处理方案是 Spring Batch 做批量。根据数据库的时间或者 ID 来进行批量处理后生成文件。然后将生成的文件放到某一个存储位置,通常可以是云存储。

前端用户只提交请求,在导出界面可以这样设计,当用户导出数据量超过 2 万后,前台页面提示说:您的导出请求已经被后台批量程序处理,请检查邮件获得下载地址。

处理策略可以使用 API 调用或者消息。

我们肯定不会做在线导出的。

3 个赞

ok, 可能我想的也没有你想的那么全面还有详细。后面我会去找产品还有业务他们协商,看看这个具体怎么处理。您的建议我都记录了下来。后面会和他们提出来这些情况。感谢大佬的建议和解答~ :smile:

1 个赞

三点建议吧:

  1. 不要所有数据写到一个文件中、分批写入。因为excel太大、即使你写进去了、别人也打不开
  2. 多个文件记录写完后我一定要压缩打包、
  3. 不要直接页面相应大文件流、这样拖累机器性能、把压缩包上传到oss这样的地方给别人下载、

楼上分析的有写道理,不过使用多线程导出百万级别数据也是可以实现的