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を使用します。