MVCC
Pertama, jika "operasi normal" terdiri dari SELECT
kueri, model MVCC akan menanganinya secara otomatis. UPDATE
tidak memblokir SELECT
dan sebaliknya. SELECT
hanya melihat data yang dikomit (atau apa yang telah dilakukan dalam transaksi yang sama), sehingga hasil UPDATE
besar tetap tidak terlihat oleh transaksi lain sampai transaksi selesai (komit).
Kinerja / kembung
Jika Anda tidak memiliki objek lain yang merujuk tabel itu,
dan Anda tidak memiliki operasi penulisan bersamaan (yang akan hilang!),
dan Anda dapat membeli kunci eksklusif yang sangat pendek di atas meja,
dan Anda memiliki ruang disk tambahan, tentu saja:
Anda dapat meminimalkan penguncian dengan membuat versi tabel yang diperbarui di latar belakang. Pastikan memiliki semuanya untuk menjadi pengganti drop-in, lalu jatuhkan yang asli dan ganti nama duplikatnya.
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;
Saya menggunakan CREATE TABLE (LIKE .. INCLUDING CONSTRAINTS)
, karena (mengutip manualnya di sini):
Batasan bukan nol selalu disalin ke tabel baru.
CHECK
batasan hanya akan disalin jikaINCLUDING CONSTRAINTS
ditentukan; jenis batasan lainnya tidak akan pernah disalin.
Pastikan, tabel baru sudah siap. Kemudian:
DROP tbl_org;
ALTER TABLE tbl_new RENAME TO tbl_org;
Menghasilkan jendela waktu yang sangat singkat, di mana tabel dikunci secara eksklusif.
Ini benar-benar hanya tentang kinerja. Itu membuat tabel baru tanpa mengasapi dengan cepat. Jika Anda memiliki kunci atau tampilan asing, Anda masih dapat menempuh rute itu, tetapi Anda harus menyiapkan skrip untuk melepaskan dan membuat ulang objek ini, yang berpotensi membuat kunci eksklusif tambahan.
Penulisan serentak
Dengan operasi penulisan bersamaan, yang dapat Anda lakukan hanyalah membagi pembaruan Anda menjadi beberapa bagian. Anda tidak dapat melakukannya dalam satu transaksi, karena kunci hanya dilepaskan pada akhir transaksi.
Anda bisa gunakan dblink , yang dapat meluncurkan transaksi independen di database lain, termasuk database itu sendiri. Dengan cara ini Anda dapat melakukan semuanya dalam satu DO
pernyataan atau fungsi plpgsql dengan loop. Berikut adalah jawaban terkait longgar dengan informasi lebih lanjut tentang dblink:
- Lepaskan atau buat database dari prosedur tersimpan di PostgreSQL
Pendekatan Anda dengan kursor
Kursor di dalam fungsi tidak akan membelikan Anda apa pun . Setiap fungsi diapit dalam transaksi secara otomatis, dan semua kunci hanya dilepaskan pada akhir transaksi. Bahkan jika Anda menggunakan CLOSE cursor
(yang tidak Anda lakukan) itu hanya akan membebaskan beberapa sumber daya, tetapi tidak lepaskan kunci yang diperoleh di atas meja. Saya mengutip manualnya:
CLOSE
menutup portal yang mendasari kursor terbuka. Ini dapat digunakan untuk melepaskan sumber daya lebih awal dari akhir transaksi, atau untuk membebaskan variabel kursor agar dapat dibuka kembali.
Anda harus menjalankan terpisah transaksi atau (ab)gunakan dblink yang melakukannya untuk Anda.