写点什么

百万级数据导出优化方案

  • 2023-05-23
    湖南
  • 本文字数:905 字

    阅读完需:约 3 分钟

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


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

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


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

方案一

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


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


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


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


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

方案二

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

  1. 还是分批次的查询,但是这时候你还是使用普通的查询,不是使用流式查询,比如一次查询 10 万条

  2. 将数据导出的文件保存到服务器的一个目录,比如文件-1

  3. 查询下一个批次的数据,数据导出的文件保存到服务器的一个目录,比如文件-2,直到将所有的数据都导出来了

  4. 数据合并,Java 是可以调 shell 脚本的,你只需要写好一个 shell 脚本将这些文件进行合并即可

  5. 合并的文件重新命名,然后将地址返回给前端

  6. 前端获取到这个文件的地址之后,就可以直接进行下载了


作者:我是小趴菜

链接:https://juejin.cn/post/7236021828999970875

来源:稀土掘金

用户头像

还未添加个人签名 2021-07-28 加入

公众号:该用户快成仙了

评论

发布
暂无评论
百万级数据导出优化方案_做梦都在改BUG_InfoQ写作社区