Saya harus memperbarui tabel 1 atau 2 miliar baris dengan berbagai nilai untuk setiap baris. Setiap proses membuat ~100 juta perubahan (10%). Percobaan pertama saya adalah mengelompokkannya dalam transaksi 300 ribu pembaruan langsung pada partisi tertentu karena Postgresql tidak selalu mengoptimalkan kueri yang disiapkan jika Anda menggunakan partisi.
- Transaksi sekumpulan "UPDATE myTable SET myField=value WHEREmyId=id"
Memberikan 1.500 pembaruan/dtk. yang berarti setiap lari akan memakan waktu setidaknya 18 jam. - Solusi pembaruan PANAS seperti yang dijelaskan di sini dengan FILLFACTOR=50. Memberikan 1.600 pembaruan/dtk. Saya menggunakan SSD, jadi ini adalah peningkatan yang mahal karena menggandakan ukuran penyimpanan.
- Sisipkan ke dalam tabel sementara dari nilai yang diperbarui dan gabungkan setelahnya dengan UPDATE...FROM Memberikan 18.000 pembaruan/dtk. jika saya melakukan VACUUM untuk setiap partisi; 100.000 up/s sebaliknya. Keren.
Inilah urutan operasinya:
CREATE TEMP TABLE tempTable (id BIGINT NOT NULL, field(s) to be updated,
CONSTRAINT tempTable_pkey PRIMARY KEY (id));
Akumulasi banyak pembaruan dalam buffer tergantung pada RAM yang tersediaSaat terisi, atau perlu mengubah tabel/partisi, atau selesai:
COPY tempTable FROM buffer;
UPDATE myTable a SET field(s)=value(s) FROM tempTable b WHERE a.id=b.id;
COMMIT;
TRUNCATE TABLE tempTable;
VACUUM FULL ANALYZE myTable;
Itu berarti lari sekarang membutuhkan waktu 1,5 jam, bukan 18 jam untuk 100 juta pembaruan, termasuk vakum. Untuk menghemat waktu, tidak perlu membuat vakum FULL di akhir tetapi bahkan vakum reguler cepat berguna untuk mengontrol ID transaksi Anda di database dan tidak mendapatkan autovacuum yang tidak diinginkan pada jam-jam sibuk.