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


10

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

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

たとえば、Oracle 11gにはそのような最適化があります。

回答:


16

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/を参照してください


4

はい、PostgreSQL 11

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

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

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

PostgreSQL 11より前の回避策

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

  • なしで列を追加する DEFAULT
  • ALTERDEFAULT後で追加するため、新しく挿入された行に適用されます
  • そして、プログレッシブバッチによって、既存の行の新しい列を移入UPDATES
  • すべての行に値がある場合、NOT NULL制約を追加します
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.