Oracle和JDBC计算事务期间发生的执行次数及其性能

时间:2013-01-31 14:28:48

标签: java sql performance oracle jdbc

我有以下代码:

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

的长度

3 个答案:

答案 0 :(得分:1)

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

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

您可以看到示例here。只需更改类型以符合您的要求,而不是执行插入,请在存储过程中执行更新:

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; 

答案 1 :(得分:0)

  1. 你是对的,通过我们正在批量执行,Oracle将在数据库上执行N个更新。

  2. 您是否考虑过通过select +存储过程通过create table批量收集/更新?

  3. 前 - 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/

答案 2 :(得分:0)

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

  

标准更新批处理的Oracle实现没有   为通用语句实现真正的批处理并且可以调用   声明。即使Oracle JDBC支持使用标准   批量处理Statement和CallableStatement对象,你不太可能   看到绩效改善。

您是否尝试过在同一文档中解释过的“Oracle Update Batching”?