2

そのため、私は 1 日の間に膨大な量のデータを 3 つのメイン テーブルに挿入するプロジェクトに取り組んでいます。3 つのテーブルはすべて相互にリンクされています。

ここにテーブルがあります:

event
    user_id
    event_time
    event_id (PRIMARY) (Serial Int)

subevent
    subevent_type
    subevent_value
    subevent_id (PRIMARY) (Serial Int)

event_relationship
    event_id (1)
    subevent_id (MANY)

eventsいつでも発生する可能性があり、発生した場合は、詳細を記録subeventsしてデータベースに挿入する必要があります。subevents1 つの に5 ~ 500 の範囲が存在する可能性がありますevent。外部キー列だけでなく関係テーブルがある理由は、親を持たないsubevents値を追加する他のプロセスがあるためです。混乱するかもしれません。subeventsevents

1 日の終わりまでに、おそらく 1000 万subeventsと 250,000を挿入したことでしょうevents。そのため、スピードは私にとって最も重要なことの 1 つです。それらをまとめて挿入するために私が見つけた最良の方法の 1 つは、DO $$ DECLARE ... END$$;コマンドを使用することです。一時整数値を宣言し、挿入する と の ID をキャプチャして、eventsそれらを一緒にテーブルsubeventsに挿入できます。event_relationship

これが私が現在実行しているコードで、PL/pgSqlとして実行されます

DO $$ DECLARE _new_event_id INTEGER; _new_subevent_id INTEGER;
BEGIN
    INSERT INTO event (user_id, event_time) VALUES (@user_id, @event_time)
    RETURNING event_id INTO _new_event_id;

    INSERT INTO subevent (subevent_type, subevent_value)
    VALUES (@subevent_type, @subevent_value)
    RETURNING subevent_id INTO _new_subevent_id;

    INSERT INTO event_relationship VALUES (_new_event_id, _new_subevent_id);

END$$;

(最初の挿入は 1 回だけで、最後の 2 つの挿入はサブイベントごとに繰り返されます。C# と NpgSql を使用してコマンドを実行し、プロセスの実行時にコマンドを動的に構築できます。)

しかし、1 日が経つにつれて、これは行き詰まり、私のデータは十分な速さですべてを挿入できないところまでバックアップし始めます。ここで間違ったアプローチをとっているのか、それとも、すでに行っていることをより高速に行う別の方法があるのか​​ 疑問に思っています。

4

2 に答える 2

1

外部キー関係を持ちnull、参照テーブルに挿入できます。

create table t (i int primary key);
create table t2 (i int references t (i));

insert into t2 (i) values (null);
INSERT 0 1

insert into t2 (i) values (1);
ERROR:  insert or update on table "t2" violates foreign key constraint "t2_i_fkey"
DETAIL:  Key (i)=(1) is not present in table "t".

または、「孤立した」サブイベントに使用される参照テーブルにゼロや -1 などの特別な値を設定します。

負荷を軽減するために、単一のコマンドでサブイベントを挿入できます。

insert into subevent (subevent_type, subevent_value) values
(@subevent1_type, @subevent1_value),
(@subevent2_type, @subevent2_value);
于 2013-08-15T20:05:01.750 に答える
0

あなたは NpgSql を使用しているので、.net 開発者だと思います。

ボトルネックが sql コマンドの作成領域にある場合は、挿入パフォーマンスを改善するためのヒントが記載された記事を次に示します。.aspx . 言及されているテクニックの中には、DbCommand.Prepare() メソッドがあります。これは、wildplasser が言及している「準備されたステートメント」に似ていると思います。

ボトルネックが実際の挿入中にある場合は、データベース サーバーへの複数の接続を使用し、複数のスレッドで作業を行うことを検討してください。

于 2013-08-15T21:21:38.150 に答える