我有以下代码:
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
答案 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)
你是对的,通过我们正在批量执行,Oracle将在数据库上执行N个更新。
您是否考虑过通过select +存储过程通过create table批量收集/更新?
前 - 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”?