【问题标题】:More efficient method for storing records from a file从文件中存储记录的更有效方法
【发布时间】:2013-07-11 04:57:45
【问题描述】:

最近在讨论中有人问我: 您有 一个 包含许多记录的平面文件,例如 500 万条记录。 您需要编写一个 Java 程序,该程序可以从该文件中获取记录并通过 JDBC 将其存储在数据库中。 最有效的方法是什么?

我的建议是创建:

  • 一个线程将处理 JDBC 连接(另外可以使连接类单例)
  • 另一个线程将从文件中获取记录并保存在表中。
  • 此外,当数据库中保存了一定数量的记录时,例如 100 条,然后先提交这些记录,然后继续。

这里存储过程会更好还是有其他方法?

【问题讨论】:

  • 如果你只是加载文件文件,Oracle有批处理文件加载器,效率更高。或者,您可以加载到临时表中并使用 SQL 来转换文件

标签: java sql oracle jdbc prepared-statement


【解决方案1】:

听起来您的想法是正确的。

花费在网络 I/O 和 DB 操作上的成本和时间将远远大于文件 IO 和解析平面文件所花费的时间。让一个单独的线程读取文件并为数据库准备记录可能会带来一些小的性能提升,但这可能不值得增加复杂性,也可能不值得 JVM 在线程管理上花费时间。我会推荐:

  • 1 个线程读取文件并提交数据库更新。
  • 正如 bitfiddler 所说,对每条记录使用带有批量更新 (preparedStatement.addBatch()) 的 PreparedStatements,并每隔“N”条记录提交一次批次 (preparedStatement.executeBatch())。您可能希望创建原型以了解“N”的理想值是多少,但 100 是一个不错的起点。

我不推荐存储过程。如果您只是直接插入,它们不会为您做很多事情。

【讨论】:

    【解决方案2】:

    好问题。在这里使用准备好的语句很重要,因为它将减少每次插入所涉及的开销。您当然不希望它每次都解析“插入等等”。我不会担心管理线程来读取文件等等,这就是操作系统为你做的事情。只需通过缓冲区读取文件的大块并从中插入。您可能会考虑通过生成多个插入器任务实例来将文件分成块,这些插入器任务从寻找文件开始并从那里读取块。操作系统应该缓冲读取,因此搜索不会很糟糕。当然,如果您的数据库不在 RAID 或至少另一个卷上,那么所有的赌注都没有了。只是一些想法来搅动锅......

    【讨论】:

    • 我不会说任何“开销”都仅限于查询解析。
    • @YourCommonSense - 同意,解析当然只是其中的一部分。
    猜你喜欢
    • 2022-09-25
    • 1970-01-01
    • 2019-01-30
    • 1970-01-01
    • 2015-08-18
    • 1970-01-01
    • 2010-12-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多