除了其他人所指的批量加载程序之外,让我们考虑如何通过 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,如果您的驱动程序支持二进制协议,可能还会节省网络流量。
测试、冲洗并重复,直到您满意为止。