DEFAULT
値を持つNOT NULL
列を追加する場合-PostgreSQLはこの操作を最適化しますか?
テーブルにn行ある場合、最適化されていないalter-table-add-columnは、デフォルト値のn回の書き込みを生成します。これは、明らかに非常に苦痛になる可能性があります。最適化により、DBは即座に新しい列を作成し、適切なインデックスデータ構造でその列の非デフォルト値が見つからない場合に返されるデフォルト値のコピーを1つだけ保存します。
たとえば Oracle 11gは など 最適化 です。
PostgreSQLにはそのようなメカニズムはありません。
ただし、このようなテーブル変更による過度の影響を回避することはできます。
次のステートメントは、ステートメント/トランザクションの間、テーブルのアクセス排他ロックを取得します。
ALTER TABLE your_table
ADD COLUMN new_column integer NOT NULL DEFAULT 0;
このステートメントはカタログを変更してから、新しい列にすべての行のデフォルト値が含まれるようにテーブル全体を書き換えます。テーブルに多くの行があり、十分な頻度でアクセスされている場合、一時的な問題が発生する可能性があります。
これを回避するには、排他ロックをできるだけ短くしてください。
ALTER TABLE your_table
ADD COLUMN new_column integer;
ALTER TABLE your_table
ALTER COLUMN new_column SET DEFAULT 0;
これは基本的にカタログへの(実際には2つの)変更(データ変更は発生しない)のみであるため、かなり高速に完了します。次に、ニーズとテーブルの使用方法に応じて、新しい列を1ステップまたはバッチでデフォルトに更新し、完了したら、列をNOT NULL
に設定します。
願いが叶うように更新します:PostgreSQL 11にはこの機能があります。参照 https://www.depesz.com/2018/04/04/waiting-for-postgresql-11-fast-alter-table-add-column-with-a-non-null-default/ 詳細については。
この機能は、バージョン11で新しく導入されました。
ALTER TABLE your_table
ADD COLUMN new_column integer NOT NULL DEFAULT 0;
上記は、この最適化の影響を受けるコマンドの1つです。ただし、NOT NULL
は必須ではありません必須ではありません。 null以外のデフォルトで追加された新しい列はすべて最適化されます。エントリは this commitfest で確認できます。これも確認してください それについてのすばらしい説明、 "Postgres 11のミッシングリンク:高速な列の作成デフォルトあり " 。
テーブルの排他的なテーブルロックを回避しようとしている場合は、Craig Ringerのアドバイスに従ってください。
DEFAULT
なしで列を追加するALTER
DEFAULT
を後で追加して、新しく挿入された行に適用するUPDATE
sにより、既存の行に新しい列を追加しますNOT NULL
制約を追加します