1

あるテーブルから他の 2 つのテーブルに 7M 行を挿入するプロセスを開始したので、これを行うためのより高速な方法があるかどうか疑問に思っています。プロセスは 1 時間で完了すると予想されます。つまり、24 時間の処理です。

手順は次のとおりです。

このテーブルのデータ

RAW (word VARCHAR2(4000), doc VARCHAR2(4000), count NUMBER);

他の 2 つのクラスタ テーブル T1 と T2 で新しいホームを見つける必要があります。

CREATE CLUSTER C1 (word VARCHAR2(4000)) SIZE 200 HASHKEYS 10000000;
CREATE CLUSTER C2 (doc VARCHAR2(4000)) SIZE 200 HASHKEYS 10000000;

T1 (word VARCHAR2(4000), doc VARCHAR2(4000), count NUMBER) CLUSTER C1(word);
T2 (doc VARCHAR2(4000), word VARCHAR2(4000), count NUMBER) CLUSTER C2(doc);

このような手動コミットでJava挿入を介して

stmtT1 = conn.prepareStatement("insert into T1 values(?,?,?)");
stmtT2 = conn.prepareStatement("insert into T2 values(?,?,?)");

rs = stmt.executeQuery("select word, doc, count from RAW");

conn.setAutoCommit(false);

while (rs.next()) {
    word = rs.getString(1);
    doc = rs.getString(2);
    count = rs.getInt(3);

    if (commitCount++==10000) { conn.commit(); commitCount=0; }

    stmtT1.setString(1, word);
    stmtT1.setString(2, doc);
    stmtT1.setInt(3, count);

    stmtT2.setString(1, doc);
    stmtT2.setString(2, word);
    stmtT2.setInt(3,count);

    stmtT1.execute();
    stmtT2.execute();
}

conn.commit();

何か案は?

4

4 に答える 4

3

最初にお勧めするのは、単純な挿入選択ステートメントを実行し、データベースにすべてのデータ移動を処理させることです。2 台のマシン間でデータを移動する場合や、クエリ全体を処理するのに十分な大きさのロールバック セグメントがない場合は、あまり役に立ちません。

2 つ目は、 addBatch()メソッドについて学ぶことです。コードを作成すると、挿入する行ごとにデータベースへの往復が行われるため、ネットワーク オーバーヘッドが追加されます。

第 3 に、目的のテーブルに既に多数の行がある場合を除き、挿入の前にインデックスを削除し、後で再作成することです。インデックスをそのままにしておくと、行ごとにインデックスを更新する必要があり、ダーティ ブロックのオーバーヘッドが増加します。

最後に、クラスタ化されたテーブルが必要ですか? 私の経験では、彼らはあなたをあまり買わないということです(注意:その経験は単一のテーブルスペースでした)。

于 2008-12-13T13:46:22.240 に答える
1

ええと、Oracle ではテーブル RAW を呼び出すことはできません。これは予約語であるため、ORA-00903 エラーが発生します。

それはさておき、次を使用します。

insert all
into t1
into t2
select * from RAW
/

「行ごとにスローごとに等しい」:)

于 2008-12-15T14:07:14.987 に答える
0

アプリでデータを処理する特別な理由がない限り、直接 INSERT AS SELECT を使用します。並列 DML を使用すると、大きな違いが得られます。

必要に応じて、INSERT ALL 構文 (1 回の読み取りで 2 回の書き込み) も確認してください。

IO の問題がない限り、1 時間で十分なはずです...

よろしく

于 2008-12-13T23:02:51.800 に答える
0

概念的には addBatch と同様に、(word、doc、count) の配列を受け取り、サーバー側で挿入を処理する PL/SQL プロシージャを作成できます。複数のレコードを一度に送信することでネットワークトリップを減らし、より高速なパフォーマンスを実現できるため、概念的には似ています。一方、サーバー側で PL/SQL を記述する必要があり、クライアント側で追加の配列ロジックが必要になるため、より複雑で脆弱です。Oracle TechNet には、この例がいくつかあります。

//ニコラス

于 2009-01-05T17:47:06.463 に答える