sql >> データベース >  >> RDS >> PostgreSQL

300万行のPostgreSQLデータベースでの遅い単純な更新クエリ

    10億行または20億行のテーブルを、行ごとにさまざまな値で更新する必要があります。実行ごとに最大1億の変更(10%)が行われます。最初の試みは、パーティションを使用する場合、Postgresqlが準備されたクエリを常に最適化するとは限らないため、特定のパーティションで直接300Kの更新のトランザクションでそれらをグループ化することでした。

    1. 「UPDATEmyTableSETmyField =value WHEREmyId=id」の束のトランザクション
      1,500を提供します 更新/秒つまり、各実行には少なくとも18時間かかります。
    2. HOTは、ここで説明されているようにFILLFACTOR=50でソリューションを更新します。 1,600回の更新/秒を提供します。 SSDを使用しているので、ストレージサイズが2倍になるため、コストがかかります。
    3. 更新された値の一時テーブルに挿入し、それらを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を制御し、ラッシュアワー中に不要な自動バキュームを取得しないようにするには、定期的なバキュームを高速化することも役立ちます。



    1. PostgreSQLのセッションIDに適したランダムな文字列をどのように作成しますか?

    2. サブクエリにないSQLselectは結果を返しません

    3. Laravelの移行でタイムスタンプ列のデフォルト値を現在のタイムスタンプに設定するにはどうすればよいですか?

    4. 3から6までのランダムなint値を生成します