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

PostgreSQL9.2でテーブルをロックせずにデータベース行を更新する

    MVCC

    まず、「通常の操作」がSELECTで構成されている場合 クエリの場合、MVCCモデルが自動的に処理します。 UPDATE SELECTをブロックしません およびその逆。 SELECT コミットされたデータ(または同じトランザクションで行われたこと)のみが表示されるため、大きなUPDATEの結果 完了する(コミットされる)まで、他のトランザクションには表示されません。

    パフォーマンス/膨張

    もし そのテーブルを参照する他のオブジェクトはありません。
    および 同時書き込み操作はありません(これは失われます!)、
    および テーブルに非常に短い専用ロックをかける余裕があります。
    および もちろん、追加のディスク容量があります。
    バックグラウンドでテーブルの更新バージョンを作成することにより、ロックを最小限に抑えることができます。 すべてがあることを確認してください ドロップインの代替品にするには、オリジナルをドロップして、デュープの名前を変更します。

    CREATE TABLE tbl_new (LIKE tbl_org INCLUDING CONSTRAINTS);
    
    INSERT INTO tbl_new 
    SELECT col_a, col_b, array[col] aS col_c
    FROM   tbl_org;
    

    CREATE TABLE (LIKE .. INCLUDING CONSTRAINTS)を使用しています 、なぜなら(ここでマニュアルを引用):

    null以外の制約は、常に新しいテーブルにコピーされます。 CHECK 制約は、INCLUDING CONSTRAINTSの場合にのみコピーされます が指定されています。他のタイプの制約はコピーされません。

    新しいテーブルの準備ができていることを確認してください。次に:

    DROP tbl_org;
    ALTER TABLE tbl_new RENAME TO tbl_org;
    

    その結果、テーブルが排他的にロックされる非常に短い時間枠になります。

    これは実際にはパフォーマンスに関するものです。膨張のない新しいテーブルをかなり迅速に作成します。外部キーまたはビューがある場合でも、そのルートに進むことができますが、これらのオブジェクトを削除して再作成するスクリプトを準備する必要があり、追加の排他ロックが作成される可能性があります。

    同時書き込み

    同時書き込み操作では、実際にできることは、更新をチャンクに分割することだけです。ロックはトランザクションの終了時にのみ解放されるため、単一のトランザクションでこれを行うことはできません。

    あなたはできた dblinkを採用する 、それ自体を含む別のデータベースで独立したトランザクションを起動できます。このようにして、すべてを1つのDOで実行できます。 ステートメントまたはループ付きのplpgsql関数。 dblinkの詳細については、大まかに関連する回答を次に示します。

    • PostgreSQLのストアドプロシージャからデータベースを削除または作成します

    カーソルを使ったアプローチ

    関数内のカーソルは何も購入しません 。すべての関数はトランザクションに自動的に含まれ、すべてのロックはトランザクションの終了時にのみ解放されます。CLOSE cursorを使用した場合でも (あなたはそうしません)それはいくつかのリソースを解放するだけですが、 テーブルで取得したロックを解放します。マニュアルを引用します:

    CLOSE 開いているカーソルの下にあるポータルを閉じます。これを使用して、トランザクションの終了前にリソースを解放したり、カーソル変数を解放して再度開くことができます。

    個別に実行する必要があります トランザクション または(ab)それを行うdblinkを使用します。




    1. SQLServer2017にアップグレードする理由

    2. newid()による注文-どのように機能しますか?

    3. SQLServerジョブを自動的に作成する

    4. date_truncPostgreSQLでは5分間隔