likes
comments
collection
share

百万级数据导出优化方案

作者站长头像
站长
· 阅读数 12

大家好我是小趴菜,数据的导出功能相信大家在平时的工作当中已经非常熟悉了。导出本来就是一个很简单的功能,使用一些工具类,然后查询出所有数据直接调用工具类就可以道出了、既然这样为什么还要写这篇文章呢??

主要是最近在做的一个功能也是导出的,但是数据量达到了百万级别、。我们知道导出的流程一般是

查询出所有要导出的数据 --->调用工具类导出

这些查询出来的数据都是放在内存中的,这时候就会有问题了。如果你的数据量特别大,大到直接把你内存撑爆了怎么办? 这时候就会报 OOM 错误了、。 下图就是我导出数据的时候内存使用图。这些数据还没有达到我线上的数据量。如果你的数据达到千万级别,那又该怎么办呢? 接下来我提供二种解决方案

百万级数据导出优化方案

方案一

无论怎么样我们都是要将所有的数据都找出来,然后导出的,既然一次性查询出来的数据量太大,我们是不是可以分批次的导出呢,比如一次就导出10万条数据,然后让前端多调几次导出的接口,这样就可以解决大数据内存占满的情况。

表面上这个问题是解决了。但是你有没有想过,前端怎么知道你有多少数据呢? 不知道数据多少又怎么知道需要调几次呢?

我既然说了可以分批次导出,那就肯定可以,既然前端不知道,那就让前端就调一次我们的接口,分批次的任务由后端解决。

相信大多数都是使用的是MyBatis,接下来我要提出的就是MyBatis的一个非常强大的功能。,那就是MyBatis的流式查询

百万级数据导出优化方案

百万级数据导出优化方案

它可以分批次查询。,所有的业务逻辑都不变,就是在将之前的普通查询改成流式查询,在使用流式查询之后,内存的使用如下图。只有100多MB,数据还是一次性的导出来了

百万级数据导出优化方案

方案二

第二种方案呢大家就比较难想到了。具体的步骤如下


1:还是分批次的查询,但是这时候你还是使用普通的查询,不是使用流式查询,比如一次查询10万条
2:将数据导出的文件保存到服务器的一个目录,比如文件-1
3:查询下一个批次的数据,数据导出的文件保存到服务器的一个目录,比如文件-2,直到将所有的数据都导出来了
4:数据合并,Java是可以调shell脚本的,你只需要写好一个shell脚本将这些文件进行合并即可
5:合并的文件重新命名,然后将地址返回给前端
6:前端获取到这个文件的地址之后,就可以直接进行下载了

总结

对于大数量的数据导出的方案我提供了二种,大家可以根据实际情况进行选择