Apakah PostgreSQL mengoptimalkan penambahan kolom dengan non-NULL DEFAULTs?

10

Saat menambahkan NOT NULLkolom dengan DEFAULTnilai - apakah PostgreSQL mengoptimalkan operasi ini?

Jika tabel memiliki n baris, kolom alter-table-add-add yang tidak dioptimalkan akan menghasilkan dan menulis nilai default - yang bisa sangat menyakitkan, jelas. Dengan optimalisasi, DB akan secara instan membuat kolom baru, menyimpan hanya satu salinan dari nilai default yang akan dikembalikan ketika tidak ada nilai non-standar ditemukan untuk kolom itu dalam struktur data indeks yang sesuai.

Misalnya Oracle 11g memiliki optimasi seperti itu .

maxschlepzig
sumber

Jawaban:

16

Tidak ada mekanisme seperti itu di PostgreSQL.

Namun, Anda masih bisa menghindari efek berlebihan dari perubahan tabel seperti itu.

Pernyataan berikut memperoleh kunci akses eksklusif di atas meja selama durasi pernyataan / transaksi:

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

Pernyataan ini mengubah katalog, lalu menulis ulang seluruh tabel sehingga kolom baru berisi nilai default di semua baris. Jika tabel memiliki banyak baris dan cukup sering diakses, ini akan menyebabkan beberapa masalah sementara.

Untuk menghindarinya, cobalah untuk memegang kunci eksklusif sesingkat mungkin:

ALTER TABLE your_table
    ADD COLUMN new_column integer;
ALTER TABLE your_table
    ALTER COLUMN new_column SET DEFAULT 0;

Karena ini pada dasarnya hanya perubahan (sebenarnya dua) ke katalog (tidak ada perubahan data terjadi), itu akan selesai dengan cepat. Kemudian tergantung pada kebutuhan dan penggunaan tabel Anda, Anda dapat memperbarui kolom baru ke default dalam satu langkah atau dalam batch, dan ketika selesai, atur kolom ke NOT NULL.

Perbarui tentang keinginan yang menjadi kenyataan: PostgreSQL 11 akan memiliki fitur ini. Lihat https://www.depesz.com/2018/04/04/ menunggu- untuk- postgresql -11- fast - alter - table - add - column - with -a- non - null - default/ untuk informasi lebih lanjut.

dezso
sumber
4

Ya, dengan PostgreSQL 11

Fitur ini baru dan masuk dalam Versi 11.

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

Di atas adalah salah satu perintah yang akan dipengaruhi oleh optimasi ini; tapi, itu harus mengatakan NOT NULLini tidak diperlukan. Setiap kolom baru yang ditambahkan dengan standar non-null dioptimalkan sekarang. Anda dapat menemukan entri di commitfest ini. Anda juga harus memeriksa artikel hebat ini tentangnya, "Tautan yang Hilang di Postgres 11: Pembuatan Kolom Cepat dengan Default" .

Solusi Pra-PostgreSQL 11

Jika Anda mencoba menghindari kunci meja eksklusif di atas meja, ikuti saran dari Craig Ringer,

  • Tambahkan kolom tanpa a DEFAULT
  • ALTERitu untuk menambahkan DEFAULTsesudahnya sehingga berlaku untuk baris yang baru dimasukkan
  • Kemudian mengisi kolom baru pada baris yang ada dengan progresif bets UPDATEs
  • Ketika semua baris memiliki nilai, Anda menambahkan NOT NULLkendala
Evan Carroll
sumber