1

最初のテーブルが非常に大きい(> 50M行)2つのテーブルがあります。

CREATE CACHED TABLE Alldistances (
    word1 VARCHAR(70), 
    word2 VARCHAR(70), 
    distance INTEGER, 
    distcount INTEGER
);

また、非常に大きくなる可能性のある1秒(> 5M行):

CREATE CACHED TABLE tempcach (
    word1 VARCHAR(70), 
    word2 VARCHAR(70), 
    distance INTEGER, 
    distcount INTEGER
);

両方のテーブルにインデックスがあります。

CREATE INDEX mulalldis ON Alldistances (word1, word2, distance);
CREATE INDEX multem ON tempcach (word1, word2, distance);

私のJavaプログラムでは、プリペアドステートメントを使用してtempcachテーブルのデータを入力/事前整理してから、テーブルを次のようにすべての距離にマージします。

MERGE INTO Alldistances alld USING ( 

    SELECT word1, 
           word2, 
           distance, 
           distcount FROM tempcach 

    ) AS src (

        newword1, 
        newword2, 
        newdistance, 
        newcount

    ) ON (

            alld.word1 = src.newword1 
        AND alld.word2 = src.newword2 
        AND alld.distance = src.newdistance 

    ) WHEN MATCHED THEN 

        UPDATE SET alld.distcount = alld.distcount+src.newcount 

    WHEN NOT MATCHED THEN 

        INSERT (

            word1, 
            word2, 
            distance, 
            distcount

        ) VALUES (

            newword1, 
            newword2, 
            newdistance, 
            newcount
        );

次に、tempchachテーブルが削除または切り捨てられ、新しいデータが入力されます。マージ中にOOMが表示されます。これは、マージ中にテーブル全体がメモリにロードされるためだと思います。したがって、バッチでマージする必要がありますが、SQLでマージすることも、Javaプログラムでマージすることもできます。または、マージ中にOOMを回避するスマートな方法はありますか?

4

2 に答える 2

0

SQLではチャンク(バッチ)にマージすることが可能です。必要がある

  • 各チャンクの一時テーブルの行数を制限する
  • それらの同じ行を削除します
  • 繰り返す

SELECTステートメントはORDERBYとLIMITを使用する必要があります

SELECT word1, 
       word2, 
       distance, 
       distcount FROM tempcach
       ORDER BY primary key or unique columns 
       LIMIT 1000

) AS src (

マージ後、deleteステートメントは削除する同じ行を選択します

DELETE FROM tempcach WHERE primary key or unique columns IN
      (SELECT primary key or unique columns FROM tempcach 
       ORDER BY primary key or unique columns LIMIT 1000)
于 2013-03-10T20:50:53.093 に答える
0

まず、この種のことが私を悩ませているという理由だけで、なぜあなたは副選択で一時テーブルのすべてのフィールドを選択するのですか?なぜもっと単純なSQLではないのですか?

MERGE INTO Alldistances alld USING tempcach AS src (
    newword1, 
    newword2, 
    newdistance, 
    newcount
) ON (
        alld.word1 = src.newword1 
    AND alld.word2 = src.newword2 
    AND alld.distance = src.newdistance 
) WHEN MATCHED THEN 
    UPDATE SET alld.distcount = alld.distcount+src.newcount 
WHEN NOT MATCHED THEN 
    INSERT (
        word1, 
        word2, 
        distance, 
        distcount
    ) VALUES (
        newword1, 
        newword2, 
        newdistance, 
        newcount
    );

データベースがテーブル全体をメモリにロードしないようにするために必要なのは、両方のテーブルのインデックス作成です。

CREATE INDEX all_data ON Alldistances (word1, word2, distance);
CREATE INDEX tempcach_data ON tempcach (word1, word2, distance);
于 2013-03-10T20:55:39.607 に答える