2

ojdbc14.jar ドライバーと Spring の SimpleJdbcTemplate batchUpdate メソッドを使用して、主キーのない Oracle 9i テーブルに 100,000 を超えるレコードを挿入しようとしています。ここに私のコードスニペットがあります:

private static final String TABLE_INSERT = "insert into TABLE_FINAL (ID, START_TIME, VALUE) VALUES (ID_SEQ.NEXTVAL, :startTime, :value)";

log.info("inputData list size={}",inputData.size());
Object[] dataArray = inputData.toArray();
log.info("dataArray length={}",dataArray.length);

final SqlParameterSource[] batch = SqlParameterSourceUtils.createBatch(inputData.toArray());
log.info("SqlParamterSource length={}", batch.length);

final int[] inserted = getJdbcTemplateJoa().batchUpdate(TABLE_INSERT, batch);

for(int i=0; i < inserted.length; i++){
if(inserted[i] != -2){
    System.out.println("i="+i +" insert[i]="+inserted[i]);
    System.out.println(batch[i]);
}

}

inputData List、dataArray、およびバッチ長のサイズはすべて同じ期待値です。batchUpdate は例外をスローせずに完了し、挿入された配列内のすべての項目が -2 (成功) を返すため、後続の for ループは何も出力しません。ただし、予期される 100,000 以上のレコードではなく、42,000 レコードのみが宛先テーブルに永続化されます。

入力コレクションをループし、アイテムごとに更新を実行して batchUpdate を置き換えると、100,000 件以上のレコードが保持されます。ただし、改善されたパフォーマンスを利用するために、batchUpdate を使用したいと考えています。

なぜ batchUpdate が機能しないのか、誰か考えはありますか? 主キーの欠落と関係があると思わざるを得ません。

以下は、inputData リストの作成に使用されるソース テーブルのデータです。

0.1933,-0.0253,0,0,4/16/2011 5:00:00 AM,4/16/2011 6:00:00 AM,12,9,1,1
0.1917,-0.0253,0,0,4/16/2011 6:00:00 AM,4/16/2011 7:00:00 AM,12,9,1,1
0.1936,-0.0253,0,0,4/16/2011 7:00:00 AM,4/16/2011 8:00:00 AM,12,9,1,1
0.2017,-0.0253,0,0,4/16/2011 8:00:00 AM,4/16/2011 9:00:00 AM,12,9,1,1
0.2083,-0.0253,0,0,4/16/2011 9:00:00 AM,4/16/2011 10:00:00 AM,12,9,1,1
0.2133,-0.0253,0,0,4/16/2011 10:00:00 AM,4/16/2011 11:00:00 AM,12,9,1,1
0.2238,-0.0253,0,0,4/16/2011 11:00:00 AM,4/16/2011 12:00:00 PM,12,9,1,1
0.2309,-0.0253,0,0,4/16/2011 12:00:00 PM,4/16/2011 1:00:00 PM,12,9,1,1
0.2319,-0.0253,0,0,4/16/2011 1:00:00 PM,4/16/2011 2:00:00 PM,12,9,1,1
0.231,-0.0253,0,0,4/16/2011 2:00:00 PM,4/16/2011 3:00:00 PM,12,9,1,1
0.2283,-0.0253,0,0,4/16/2011 3:00:00 PM,4/16/2011 4:00:00 PM,12,9,1,1
0.2216,-0.0253,0,0,4/16/2011 4:00:00 PM,4/16/2011 5:00:00 PM,12,9,1,1
0.2164,-0.0253,0,0,4/16/2011 5:00:00 PM,4/16/2011 6:00:00 PM,12,9,1,1
0.2155,-0.0253,0,0,4/16/2011 6:00:00 PM,4/16/2011 7:00:00 PM,12,9,1,1
0.2162,-0.0253,0,0,4/16/2011 7:00:00 PM,4/16/2011 8:00:00 PM,12,9,1,1
0.2187,-0.0253,0,0,4/16/2011 8:00:00 PM,4/16/2011 9:00:00 PM,12,9,1,1
0.2203,-0.0253,0,0,4/16/2011 9:00:00 PM,4/16/2011 10:00:00 PM,12,9,1,1
0.2296,-0.0253,0,0,4/16/2011 10:00:00 PM,4/16/2011 11:00:00 PM,12,9,1,1
0.2323,-0.0253,0,0,4/16/2011 11:00:00 PM,4/17/2011,12,9,1,1
0.2293,-0.0253,0,0,4/17/2011,4/17/2011 1:00:00 AM,12,9,1,1
0.2154,-0.0253,0,0,4/17/2011 1:00:00 AM,4/17/2011 2:00:00 AM,12,9,1,1
0.2088,-0.0253,0,0,4/17/2011 2:00:00 AM,4/17/2011 3:00:00 AM,12,9,1,1
0.202,-0.0253,0,0,4/17/2011 3:00:00 AM,4/17/2011 4:00:00 AM,12,9,1,1
0.1916,-0.0253,0,0,4/17/2011 4:00:00 AM,4/17/2011 5:00:00 AM,12,9,1,1

そして、batchUpdate 後に保持されるものは次のとおりです。

47987296,4/19/2011 4:37:15 PM,0.1933,-0.0253,4/16/2011 5:00:00 AM,4/16/2011 6:00:00 AM,4/19/2011 4:37:28 PM,9,12,1,1,04-15-2011 
47961249,4/19/2011 4:37:15 PM,0.2238,-0.0253,4/16/2011 11:00:00 AM,4/16/2011 12:00:00 PM,4/19/2011 4:37:28 PM,9,12,1,1,04-15-2011 
47966094,4/19/2011 4:37:15 PM,0.2309,-0.0253,4/16/2011 12:00:00 PM,4/16/2011 1:00:00 PM,4/19/2011 4:37:28 PM,9,12,1,1,04-15-2011 
47968596,4/19/2011 4:37:15 PM,0.2319,-0.0253,4/16/2011 1:00:00 PM,4/16/2011 2:00:00 PM,4/19/2011 4:37:28 PM,9,12,1,1,04-15-2011 
47972962,4/19/2011 4:37:15 PM,0.231,-0.0253,4/16/2011 2:00:00 PM,4/16/2011 3:00:00 PM,4/19/2011 4:37:28 PM,9,12,1,1,04-15-2011 
47978129,4/19/2011 4:37:15 PM,0.2283,-0.0253,4/16/2011 3:00:00 PM,4/16/2011 4:00:00 PM,4/19/2011 4:37:28 PM,9,12,1,1,04-15-2011 
47982943,4/19/2011 4:37:15 PM,0.2216,-0.0253,4/16/2011 4:00:00 PM,4/16/2011 5:00:00 PM,4/19/2011 4:37:28 PM,9,12,1,1,04-15-2011 
48005719,4/19/2011 4:37:15 PM,0.2164,-0.0253,4/16/2011 5:00:00 PM,4/16/2011 6:00:00 PM,4/19/2011 4:37:28 PM,9,12,1,1,04-15-2011 
47990490,4/19/2011 4:37:15 PM,0.2088,-0.0253,4/17/2011 2:00:00 AM,4/17/2011 3:00:00 AM,4/19/2011 4:37:28 PM,9,12,1,1,04-15-2011 
47993531,4/19/2011 4:37:15 PM,0.202,-0.0253,4/17/2011 3:00:00 AM,4/17/2011 4:00:00 AM,4/19/2011 4:37:28 PM,9,12,1,1,04-15-2011 
48000722,4/19/2011 4:37:15 PM,0.1916,-0.0253,4/17/2011 4:00:00 AM,4/17/2011 5:00:00 AM,4/19/2011 4:37:28 PM,9,12,1,1,04-15-2011 

ソース テーブルの 24 行は、宛先テーブルにも 24 行あるはずですが、データが取り込まれるのは 11 行のみです。

4

2 に答える 2

1

ojdbc14.jar と大量のデータ (60K 以上) で SimpleJdbcTemplate.batchUpdate(String sql, SqlParameterSource[] source) を使用すると、最初の投稿で説明したように、宛先テーブルからデータが失われました。入力データを 10K チャンクに分割すると、データが正常に保持されることがわかりました。また、正しく持続する JdbcTemplate.batchUpdate(String [] sql) メソッドを使用してみましたが、ループして SimpleJdbcTemplate.update を呼び出すよりも遅くなりました。プラス面として、 JdbcTemplate.batchUpdate(String [] sql) は int[] を返します。配列内の各項目には、影響を受ける行数が含まれています。

Oracle ドライバーを ojdbc6.jar に変更し、SimpleJdbcTemplate.batchUpdate(String sql, SqlParamterSource[] source) を使用して再テストし、100,000 以上のソース レコードすべてを渡しました。残念ながら、oj​​dbc14.jar を必要とする他の依存関係があるため、まだアップグレードできません。

最終的な解決策として、データは以下に示すように 10K のチャンクに分割され、データが永続化されたことを検証する SQL クエリが batchUpdate の後に追加されます。

if(inputData.size() > 10000){

            int beginIndex =0;
            int endIndex = 10000;
            List<InputData> partialList = null;
            while(beginIndex < inputData.size()){
                partialList = inputData.subList(beginIndex, endIndex);

                final SqlParameterSource[] batch = SqlParameterSourceUtils.createBatch(partialList.toArray());

                getJdbcTemplateJoa().batchUpdate(TABLE_INSERT, batch);

                beginIndex = endIndex;
                endIndex = endIndex + 10000 < inputData.size() ? endIndex + 10000 : inputData.size();
            }
} else{

            final SqlParameterSource[] batch = SqlParameterSourceUtils.createBatch(inputData.toArray());
            getJdbcTemplateJoa().batchUpdate(TABLE_INSERT, batch);

        }
于 2011-05-05T17:51:16.267 に答える
0

おそらく、キャッチされて通過しなかった例外があった可能性があります。トリガーをインストールしservererrorて、Oracle がクライアントに例外を渡したかどうかを確認してください。

ここに例があります。

ところで、それが機能したら、パフォーマンスの向上に興味があります。変わらなくても不思議じゃない……。

于 2011-04-20T14:40:30.717 に答える