我正在 Java Spring 中开发一个 Web 应用程序,我希望用户能够从前端上传 CSV 文件,然后查看导入过程的实时进度,导入后他应该能够从导入的数据中搜索各个条目。
导入过程包括实际上传文件(通过 REST API POST 请求发送),然后读取文件并将其内容保存到数据库中,以便用户能够从此数据中进行搜索。
将数据保存到数据库的最快方法是什么?仅循环各行并创建一个新的类对象并通过 JPARepository 为每行保存它会花费太多时间。 10000 行大约需要 90 秒。我需要让它变得更快。我需要在合理的时间内添加 200k 行。
旁注:
我看到了使用 Reactor 的异步方法。这应该会更快,因为它使用多个线程,并且保存行的顺序基本上并不重要(尽管数据在 CSV 中具有 ID)。
然后我还看到了 Spring Batch 作业,但所有示例都使用 SQL。我正在使用存储库,因此我不确定是否可以使用它或者它是否是最佳方法。
最佳答案
This GitHub 存储库比较了 5 种不同的批量插入数据的方法。附件。给他,使用 JdbcTemplate
是最快的(他声称在 1.79 [+- 0.50] 秒内处理了 500000 条记录)。如果您使用JdbcTemplate
使用 Spring Data,您需要创建一个自定义存储库;请参阅this有关详细说明的文档中的部分。
Spring 数据CrudRepository
有一个save
需要 Iterable
的方法,所以您也可以使用它,尽管您必须计时以查看它相对于 JdbcTemplate
的性能如何。 。使用Spring Data,步骤如下(摘自here,经过一些编辑)
- 地址:
rewriteBatchedStatements=true
到连接字符串的末尾。 确保您使用的生成器支持实体中的批处理。例如
@Id @GeneratedValue(generator = "generator") @GenericGenerator(name = "generator", strategy = "increment")
使用:
save(Iterable<S> entities)
CrudRepository
的方法保存数据。- 使用:
hibernate.jdbc.batch_size
配置。
解决方案 #2 的代码是 here .
至于使用多个线程,请记住,从多个线程写入数据库中的同一个表可能会产生表级争用并产生更糟糕的结果。你必须尝试并计时。如何使用 Reactor 项目编写多线程代码是一个完全独立的主题,超出了本文的范围。
HTH。
关于Java Spring : How to efficiently read and save large amount of data from a CSV file?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44936375/