web-dev-qa-db-ja.com

PostgreSQLはNULL以外のDEFAULTを含む列の追加を最適化しますか?

DEFAULT値を持つNOT NULL列を追加する場合-PostgreSQLはこの操作を最適化しますか?

テーブルにn行ある場合、最適化されていないalter-table-add-columnは、デフォルト値のn回の書き込みを生成します。これは、明らかに非常に苦痛になる可能性があります。最適化により、DBは即座に新しい列を作成し、適切なインデックスデータ構造でその列の非デフォルト値が見つからない場合に返されるデフォルト値のコピーを1つだけ保存します。

たとえば Oracle 11gは など 最適化 です。

9
maxschlepzig

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/ 詳細については。

15
dezso

はい、PostgreSQL 11

この機能は、バージョン11で新しく導入されました。

ALTER TABLE your_table
    ADD COLUMN new_column integer NOT NULL DEFAULT 0;

上記は、この最適化の影響を受けるコマンドの1つです。ただし、NOT NULLは必須ではありません必須ではありません。 null以外のデフォルトで追加された新しい列はすべて最適化されます。エントリは this commitfest で確認できます。これも確認してください それについてのすばらしい説明、 "Postgres 11のミッシングリンク:高速な列の作成デフォルトあり "

PostgreSQL 11より前の回避策

テーブルの排他的なテーブルロックを回避しようとしている場合は、Craig Ringerのアドバイスに従ってください。

  • DEFAULTなしで列を追加する
  • ALTERDEFAULTを後で追加して、新しく挿入された行に適用する
  • 次に、プログレッシブバッチUPDATEsにより、既存の行に新しい列を追加します
  • すべての行に値がある場合、NOT NULL制約を追加します
3
Evan Carroll