2012-01-05 15 views
8

Apache Derbyを使用して、数百万の10のオーダーの大量の行を格納しています。私が一括挿入を開始するたびに、私は2ミリオン以上の行をテーブルに挿入します。 テーブルには、プライマリキーとしてのUUIDと、他の1つのテーブル内のUUIDに対する単一の制約があります。 挿入に時間がかかります!どうして ? すべてのテーブルでINDEXを作成しましたが、これ以降、Derbyがプライマリキーを持つ各テーブルのINDEXを自動的に作成すると考えているため、これを削除しました。私はより多くの行を挿入したよう が示すように、私は結果がApache Derby INSERTSが遅い

05/01/12 12:42:48 Creating 2051469 HE Peaks in DB Table APP.ST_HE_PEAK_TABLE 
05/01/12 12:44:18 Progress: Written (10%) 205146/2051469 entries to DB Table APP.ST_HE_PEAK_TABLE 
05/01/12 12:46:51 Progress: Written (20%) 410292/2051469 entries to DB Table APP.ST_HE_PEAK_TABLE 
05/01/12 12:50:46 Progress: Written (30%) 615438/2051469 entries to DB Table APP.ST_HE_PEAK_TABLE 05/01/12 12:56:46 Progress: Written (40%) 820584/2051469 entries to DB Table APP.ST_HE_PEAK_TABLE 
05/01/12 13:04:29 Progress: Written (50%) 1025730/2051469 entries to DB Table APP.ST_HE_PEAK_TABLE 
05/01/12 13:13:19 Progress: Written (60%) 1230876/2051469 entries to DB Table APP.ST_HE_PEAK_TABLE 
05/01/12 13:22:54 Progress: Written (70%) 1436022/2051469 entries to DB Table APP.ST_HE_PEAK_TABLE 
05/01/12 13:34:53 Progress: Written (80%) 1641168/2051469 entries to DB Table APP.ST_HE_PEAK_TABLE 
05/01/12 13:47:02 Progress: Written (90%) 1846314/2051469 entries to DB Table APP.ST_HE_PEAK_TABLE 
05/01/12 13:58:09 Completed: Written (100%) 2051469/2051469 entries to DB Table APP.ST_HE_PEAK_TABLE - Time Taken:01:15:21 

です。ここ(以下、非常に単純な形で)準備されたステートメントで

final PreparedStatement addStatement = connection.prepareStatement(...) 
int entryCount = 0; 
    for (final T entry : entries) { 
    addStatement.addBatch(); 
    entryCount++; 
    if (entryCount % 1000 == 0) { 
    addStatement.executeBatch(); 
    addStatement.clearBatch(); 
    entryCount = 0; 
    } 
addStatement.close(); 

をバッチ更新を使用しています、プロセスが遅くなると、遅い(おそらくINDEXのため)。私が現時点で持っているDBモデルは、私の目的をうまく果たしており、私はそれを変更することを嫌いです。 何か間違っていますか? ...またはあまりにも多くを期待していますか? INSERTの速度を向上させる方法はありますか?


編集

私はすでに自動コミットなどを使用してDBにチューニングされています。何百万というレコードをINSERTすると、アプリケーションに無理な時間がかかることがわかりました。もちろん、このデータのSELECTは非常に高速です。

+0

データをDerbyでディスクに永続化し、最後のレコードIDの時点でリモート・データをロードできます。 _(明白にごめんなさい)_ –

答えて

8

自動コミットモードをオフにしましたか? http://db.apache.org/derby/docs/dev/tuning/tuningderby.pdf

各コミットには、各INSERTステートメントのディスク上のログの更新が含まれているため、自動コミットモードでは挿入が苦労する可能性があります。物理ディスク書き込みが実行されるまでコミットは返されません。 物事をスピードアップするには、次の自動コミット偽モードで

  • を実行し、1つのトランザクションで挿入の数を実行し、 は、明示的にコミットを発行。
  • アプリケーションで表に最初のロードが許可されている場合は、インポート手順 を使用して表にデータを挿入できます。これらのインターフェースを使用して空の表に がロードされると、Derbyは個々の挿入をログに記録しません。 インポート・プロシージャの詳細は、Derbyリファレンス ManualおよびDerby Server and Administration Guideを参照してください。
+0

あなたのお返事ありがとうございます。私はすでに自動コミットなどを使用してDBをチューニングしています。何百万というレコードをINSERTすると、アプリケーションに無理な時間がかかることがわかりました。もちろん、このデータのSELECTは非常に高速です。私は自分のDBを再構成して、ProtocolBuffersを使ってオブジェクトのコレクションを書く必要がありました。非常に高速です。データを使用するときはいつでも、オブジェクトのコレクション全体をロードする必要がありますが、これは私にとっては十分です。 –

+0

@AndyTudor - あなたは説明することができます: "私はあなたのDBを再構成して、ProtocolBuffersを使ったオブジェクトのコレクションを非常にうまく書いていなければならず、非常に高速です - ただ使いたいときはいつでもオブジェクトのコレクション全体をロードしなければならないデータ"。私は同様の挑戦に直面しており、これが私にもできることであるかどうかを知りたい – donlys

関連する問題