10億行または20億行のテーブルを、行ごとにさまざまな値で更新する必要があります。実行ごとに最大1億の変更(10%)が行われます。最初の試みは、パーティションを使用する場合、Postgresqlが準備されたクエリを常に最適化するとは限らないため、特定のパーティションで直接300Kの更新のトランザクションでそれらをグループ化することでした。
- 「UPDATEmyTableSETmyField =value WHEREmyId=id」の束のトランザクション
は1,500を提供します 更新/秒つまり、各実行には少なくとも18時間かかります。 - HOTは、ここで説明されているようにFILLFACTOR=50でソリューションを更新します。 1,600回の更新/秒を提供します。 SSDを使用しているので、ストレージサイズが2倍になるため、コストがかかります。
- 更新された値の一時テーブルに挿入し、それらをUPDATEでマージします...FROMは18,000を提供します 更新/秒パーティションごとにVACUUMを実行した場合。それ以外の場合は100,000up/s。 Cooool。
操作の順序は次のとおりです。
CREATE TEMP TABLE tempTable (id BIGINT NOT NULL, field(s) to be updated,
CONSTRAINT tempTable_pkey PRIMARY KEY (id));
使用可能なRAMに応じて、バッファに大量の更新を蓄積します。RAMがいっぱいになったとき、テーブル/パーティションを変更する必要があるとき、または完了したとき:
COPY tempTable FROM buffer;
UPDATE myTable a SET field(s)=value(s) FROM tempTable b WHERE a.id=b.id;
COMMIT;
TRUNCATE TABLE tempTable;
VACUUM FULL ANALYZE myTable;
つまり、1億回の更新では、実行に18時間ではなく1.5時間かかるようになり、バキュームが含まれます。時間を節約するために、最後にバキュームをFULLにする必要はありませんが、データベースのトランザクションIDを制御し、ラッシュアワー中に不要な自動バキュームを取得しないようにするには、定期的なバキュームを高速化することも役立ちます。