を使用している場合、行を挿入してから追加する方がパフォーマンスが向上するということは、ほとんど意味がありませんbytea
。
PostgreSQL の MVCC 設計は、 anが aおよび anUPDATE
と論理的に同等であることを意味します。行を挿入してから更新すると、挿入した元のタプルが削除済みとしてマークされ、古いデータと追加されたデータの連結を含む新しいタプルが書き込まれます。DELETE
INSERT
あなたのテスト方法について質問します。挿入してから追加する方が速いと判断した理由を詳しく説明していただけますか? 意味がない。
それを超えて、この質問は広すぎて、実際に多くのことを言うには書かれていないと思います。詳細や数値は提供していません。バイナリ データ サイズの見積もり、行数の見積もり、クライアント数の見積もりなどはありません。
bytea
挿入パフォーマンスは、PostgreSQL の他の挿入パフォーマンス チューニングと変わりません。同じアドバイスがすべて当てはまります: バッチ作業をトランザクションに分割し、複数の同時セッションを使用して (ただし、多すぎない; 経験則は number_of_cpus + number_of_hard_drives です) データを挿入し、トランザクションが互いのデータを使用しないようにしてUPDATE
、ロックを必要としないようにします。バッテリでバックアップされた RAID コントローラなどのような安全なライトバック キャッシュを備えたディスク サブシステムがない場合は、async commit および/または commit_delay を使用します。
メインのコメント スレッドで提供された最新の統計情報を考えると、消費したいデータの量は、適切なハードウェアとアプリケーションの設計で完全に実用的なように思えます。入ってくるすべてのブロックをコミットしなければならない場合、1 秒あたり約 60 のトランザクションが必要になるため、通常のハード ドライブでもピーク負荷を達成できる可能性があります。を使用しcommit_delay
て、グループ コミットを達成し、fsync() のオーバーヘッドを大幅に削減したりsynchronous_commit = off
、クラッシュの場合にトランザクションのタイム ウィンドウを失う余裕がある場合に使用することもできます。
バッテリ バックアップ式のキャッシュ RAID コントローラや信頼性の高い電力損失セーフ キャッシュを備えた SSD などのライトバック キャッシュ ストレージ デバイスを使用すると、この負荷に簡単に対処できます。
これについてさまざまなシナリオのベンチマークを行っていないため、一般的な用語しか話せません。これを自分で設計する場合、PostgreSQL でのチェックポイント ストールが心配になり、少しのデータをバッファリングできることを確認したいと思います。できるようですので、大丈夫なはずです。
私の見解では、おそらく最も実用的であるため、テスト、ベンチマーク、および負荷テストを行う最初のアプローチを次に示します。
データ ストリームごとに 1 つの接続synchronous_commit = off
+ a commit_delay
.
INSERT
16kb の各レコードがステージング テーブルに入ると (可能であればUNLOGGED
、またはTEMPORARY
不完全なレコードを失う余裕がある場合)、Pg にコミットを同期させてグループ化させます。各ストリームが終了したら、バイト配列を読み取り、それらを連結して、レコードを最終テーブルに書き込みます。
このアプローチで最高の速度を得るには、bytea_agg
集計関数をbytea
拡張モジュールとして実装します (そして、将来のバージョンに含めるために PostgreSQL に送信します)。実際には、データを読み取るか、非効率的で非線形のスケーリングを使用して、アプリケーションで bytea 連結を実行することで回避できる可能性があります。
CREATE AGGREGATE bytea_agg(bytea) (SFUNC=byteacat,STYPE=bytea);
INSERT INTO final_table SELECT stream_id, bytea_agg(data_block) FROM temp_stream_table;
チェックポインティングの動作を確実に調整する必要があります。これらの 16kb レコードを蓄積するためにUNLOGGED
テーブルではなく通常のテーブルまたはテーブルを使用しているTEMPORARY
場合は、それがかなり積極的にVACUUM
編集されていることを確認する必要があります。
以下も参照してください。