1

PostgreSQLのパーティションテーブルに毎日何百万もの行を書き込む大規模なWebアプリがあります(つまり、毎日のデータ用に新しいテーブルがあります)。

PostgreSQLのテーブル継承とパーティショニングを使用して、処理を高速化します。

DBには1年分のデータがあるため、挿入トリガーを効果的に使用してコンテンツを正しいテーブルにルーティングすることはできません(関数の長さが非常に長くなっています)。

insert簡単に言うと、どのテーブルにupdateデータを保存するかを知るにはActiveRecordが必要です。ただし、selectやその他のDBタスクに使用されるテーブルは変更しないでください。

明らかに、モデルのテーブル名を定義するのは簡単ですが、特定のアクションだけのテーブル名をオーバーライドすることは可能ですか?

もう少し詳しく説明します。

データベース:

  • テーブル: dashboard.impressions(id、host、data、created_onなど)
  • テーブル: data.impressions_20120801(dashboard.impressionsから継承され、created_onの制約はテーブルの日付と同じです)

Impression.create :host=>"localhost", :data=>"{...}", created_on=>DateTime.nowdata.impressions_20120801テーブルに書き込む必要があります。テーブルにはすべてのデータが含まれているためImpression.where(:host=>"localhost")、テーブルを検索する必要があります。dashboard.impressions

編集:PostgreSQL9.1とRails3.2.6を実行しています

4

1 に答える 1

1

私は Rails を扱っていないので、ActiveRecord 側を支援することはできませんが、ActiveRecord でやり​​たいことを実行できない場合に備えて、純粋な Pg フォールバック ソリューションを提供できます。挿入のパフォーマンスが少し低下するので、適切な場所に挿入するように ActiveRecord に教えた方がはるかに優れています。

個人的にはINSERT、gem を介して直接 s を実行し、 pgActiveRecord を完全にバイパスします。それができない場合、または ActiveRecord がキャッシングを行っているためそうすべきでない場合は、この別のパーティショニング トリガーの実装を試してください。

トリガー関数ですべてのパーティションを明示的にリストする代わりに、EXECUTE ... USING挿入を検討し、命名スキームを使用してパーティション名を生成します。テストされていないようなもの:

CREATE OR REPLACE FUNCTION partition_trigger() RETURNS trigger AS $$
DECLARE
    target_partition text;
BEGIN
    IF tg_op = 'INSERT' THEN
        target_partition = ( ... work out the partition name ... )
        EXECUTE 'INSERT INTO '||quote_ident(target_partition)||' (col1,col2) VALUES ($1, $2)'
            USING (NEW.col1, NEW.col2);
    END IF;
    RETURN NULL;
END;
$$ LANGUAGE 'plpgsql';
于 2012-08-29T02:08:04.897 に答える