【问题标题】:Fastest way for doing INSERTS using IBATIS使用 IBATIS 进行 INSERTS 的最快方法
【发布时间】:2010-09-22 05:48:33
【问题描述】:

我需要使用 iBatis 在单个表 (SQL Server 2005) 中插入 20,000 行。最快的方法是什么?我已经在使用批处理模式,但没有多大帮助:

try {
  sqlMap.startTransaction();
  sqlMap.startBatch();
  // ... execute statements in between
  sqlMap.commitTransaction();
} finally {
  sqlMap.endTransaction();
}

【问题讨论】:

    标签: java ibatis bulkinsert


    【解决方案1】:

    除了其他人所指的批量加载程序之外,让我们考虑如何通过 SQL 最好地做到这一点。 (如果您将混合数据发送到不同的表,批量加载程序就无法正常工作。)

    首先,您不应该使用您正在使用的任何抽象层,在本例中为 iBatis,因为它实际上不会为您提供很少的价值,但该抽象层将有一些(不一定很多,但有一些)CPU 成本.您真的应该简单地使用原始数据库连接。

    接下来,您将发送一堆 INSERT 语句。问题是您是否应该对语句使用简单的字符串(即 INSERT INTO TABLE1 VALUES('x','y', 12))与准备好的语句(INSERT INTO TABLE1 VALUES(?, ?, ?))。

    这将取决于您的数据库和数据库驱动程序。

    使用简单字符串的问题基本上是从内部格式(假设您插入 Java 数据)到字符串的转换成本。将数字或日期转换为字符串实际上是相当昂贵的 CPU 操作。一些数据库和驱动程序将直接处理二进制数据,而不是简单的字符串数据。因此,在这种情况下,PreparedStatement 可以节省一些 CPU,而不必转换数据。

    缺点是这个因素会因数据库供应商而异,甚至可能因 JDBC 供应商而异。例如,Postgres(我相信)只适用于 SQL 字符串,而不是二进制,所以使用 PreparedStatement 比简单地自己构建字符串是一种浪费。

    接下来,一旦您有了自己的语句类型,您就想使用 JDBC Statement 类的addBatch() 方法。 addBatch 所做的是将 SQL 语句分组到一个批处理中。好处是,您无需向数据库发送多个请求,而是发送一个 LARGE 请求。这会减少网络流量,并会显着提高吞吐量。

    细节是不是所有的驱动程序/数据库都支持 addBatch(至少不是很好),而且你的批处理大小是有限的。您很可能无法为所有 20,000 行添加批处理并期望它能够正常工作,尽管那将是最好的选择。此限制也可能因数据库而异。

    对于 Oracle,过去我使用 64K 的缓冲区。基本上我写了一个包装函数,它会接受一个文字 INSERT 语句,并将它们累积成 64K 批次。

    因此,如果您想通过 JDBC 通过 SQL 批量插入数据,那么可以采用这些方法。最大的改进是批处理模式,Statement 与 PreparedStatement 更可能节省一些 CPU,如果您的驱动程序支持二进制协议,可能还会节省网络流量。

    测试、冲洗并重复,直到您满意为止。

    【讨论】:

      【解决方案2】:

      虽然这不是特定于您的数据库服务器,但我之前已经成功地将行以 csv 格式写入本地文件,然后让数据库导入文件。这比插入语句甚至批量插入要快得多。

      【讨论】:

      • 最近在 MySQL 上获得了同样的体验:使用从文件加载的普通 INSERT INTO 语句插入数据比使用上述批量插入要快得多。
      【解决方案3】:

      在 SQL Server 中,批量插入记录的最快方法是使用BULK INSERT。但是,此方法从文本文件而不是直接从您的应用程序加载记录。

      它也没有考虑创建文件所花费的时间。如果这抵消了实际插入的任何速度增益,您可能需要权衡。请记住,即使整体速度稍慢,您最终占用数据库服务器的时间也会更短。

      您可能会尝试的唯一另一件事是将批处理插入(暂存)到一个完全不同的表中(没有索引或任何东西)。然后将记录从该临时表移动到您的目标表并删除临时表。这将首先将数据移动到服务器,以便最终插入都可能发生在 sql server 本身。但同样:这是一个两步过程,所以你必须计算这两个步骤的时间。

      【讨论】:

      • +1 从文件中批量加载。编写平面文件的速度通常非常快。
      【解决方案4】:

      批量插入最好使用数据库自​​己的批量加载工具来完成。例如,对于 Oracle,它是 SQL*Loader。这些通常比你写的任何东西都快。

      【讨论】:

        猜你喜欢
        • 2016-10-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-23
        • 1970-01-01
        • 2012-03-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多