0

我有以下代码:

void updateRecords(long[] ids, Timestamp[] dates, Connection connection
{
   PreparedStatement statement = connection.prepareStatement(
                             "Update Foo set date = ? where id = ?");
   for(int i =0; i < ids.length;i++)
   {
        statement.setTimestamp(1,dates[i]);
        statement.setLong(2,ids[i]);  
        statement.addBatch();  
        if(i %25000 == 0)
        {
            statement.executeBatch();
            statement.clearBatch();  
        }
   }
   statement.executeBatch();
}

这个性能很糟糕,100 万次更新需要 2 个小时以上。所以在我的多部分问题中:

1) 在 Oracle 上执行了多少条语句?
2) 如何提高在 Oracle 上执行的语句数量,以减少执行 100 万次更新所需的时间?

这是 Oracle 10g 和 Java 6。

我想这会执行 N 个语句,其中 N 是ids

4

3 回答 3

1

1) 是的,oracle 将执行与 id 一样多的语句。

2)对于这样的事情,最好的办法是在一次调用中将日期发送到数据库,然后使用存储过程进行更新。例如,您可以将 ids 和 Timestamps 作为数组发送,然后在存储过程中重新创建您的逻辑。此外,根据您的数据库结构和配置,在存储过程中每隔一段时间运行一次提交可以提高性能(假设您的操作不必是原子的)。

你可以在这里看到一个例子。只需更改类型以符合您的要求,而不是进行插入,而是在存储过程中进行更新:

forall i in 1.. example.count 
  update Foo set date =  treat(example(i) as T_TYPE).DATE where id = treat(example(i) as T_TYPE).ID;
end; 
于 2013-01-31T14:43:03.927 回答
0

似乎使用标准 JDBC 批处理并没有减少往返次数,请参阅 Oracle JDBC Developer's Guide and Reference

标准更新批处理的 Oracle 实现没有为通用语句和可调用语句实现真正的批处理。即使 Oracle JDBC 支持对 Statement 和 CallableStatement 对象使用标准批处理,您也不太可能看到性能改进。

您是否尝试过他们自己在同一文档中解释的“Oracle 更新批处理”?

于 2013-01-31T16:05:17.243 回答
0
  1. 你是对的,通过我们批量执行,Oracle 将在数据库上执行 N 次更新。

  2. 您是否考虑过通过选择 + 存储过程通过创建表使用批量收集/更新?

ex -create table Foo2 as select c1, c2, c3, <<date>> from Foo; 现在删除 Foo 并将 Foo2 重命名为 Foo 表。

请参阅以下链接了解更多信息。

http://ksadba.wordpress.com/2008/06/16/updating-millions-of-rows-merge-vs-bulk-collect/

于 2013-01-31T14:44:40.433 回答