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)このような場合、最善の策は、データベースへの1回の呼び出しで日付を送信してから、ストアドプロシージャを使用して更新を行うことです。たとえば、IDとタイムスタンプを配列として送信してから、ストアドプロシージャでロジックを再作成できます。また、データベースの構造と構成によっては、ストアドプロシージャ内で頻繁にコミットを実行すると、パフォーマンスが向上する可能性があります(操作がアトミックである必要がない場合)。

ここで例を見ることができます。要件に合わせてタイプを変更するだけで、挿入を行う代わりに、ストアード・プロシージャー内で更新を実行します。

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
  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 に答える