Menggunakan PG 9.1 di Ubuntu 12.04.
Saat ini diperlukan waktu hingga 24 jam bagi kami untuk menjalankan serangkaian besar pernyataan UPDATE pada database, yang berbentuk:
UPDATE table
SET field1 = constant1, field2 = constant2, ...
WHERE id = constid
(Kami hanya menimpa bidang objek yang diidentifikasi oleh ID.) Nilai-nilai tersebut berasal dari sumber data eksternal (belum ada dalam DB dalam tabel).
Tabel memiliki beberapa indeks masing-masing dan tidak ada batasan kunci asing. Tidak ada KOMIT yang dibuat sampai akhir.
Diperlukan 2 jam untuk mengimpor a pg_dump
dari seluruh DB. Ini terlihat seperti garis dasar yang harus kita targetkan secara wajar.
Kurang menghasilkan program khusus yang entah bagaimana merekonstruksi set data untuk PostgreSQL untuk diimpor kembali, adakah yang bisa kita lakukan untuk membawa kinerja UPDATE massal lebih dekat dengan impor? (Ini adalah area yang kami yakini dapat menangani pohon gabungan dengan struktur log, tapi kami bertanya-tanya apakah ada yang bisa kami lakukan di dalam PostgreSQL.)
Beberapa ide:
- menjatuhkan semua indeks non-ID dan membangun kembali sesudahnya?
- meningkatkan checkpoint_segments, tetapi apakah ini benar-benar membantu throughput jangka panjang yang berkelanjutan?
- menggunakan teknik yang disebutkan di sini ? (Muat data baru sebagai tabel, lalu "gabungkan" data lama di mana ID tidak ditemukan dalam data baru)
Pada dasarnya ada banyak hal untuk dicoba dan kami tidak yakin apa yang paling efektif atau jika kita mengabaikan hal-hal lain. Kami akan menghabiskan beberapa hari berikutnya bereksperimen, tetapi kami pikir kami akan bertanya di sini juga.
Saya memiliki beban bersamaan di atas meja tetapi hanya-baca.
explain analyze
bahwa itu menggunakan indeks untuk pencarian?Jawaban:
Asumsi
Karena informasi tidak ada dalam Q, saya akan menganggap:
COPY
output, dengan unikid
per baris untuk mencocokkan tabel target.Jika tidak, format terlebih dahulu dengan benar atau gunakan
COPY
opsi untuk menangani format.Itu berarti tidak ada akses bersamaan. Lain pertimbangkan jawaban terkait ini:
Larutan
Saya sarankan Anda pergi dengan pendekatan yang sama seperti yang diuraikan di tautan dari peluru ketiga Anda . Dengan optimasi besar.
Untuk membuat tabel sementara, ada cara yang lebih sederhana dan lebih cepat:
Satu besar
UPDATE
dari tabel sementara di dalam database akan lebih cepat daripada pembaruan individu dari luar database dengan beberapa urutan besarnya.Dalam model MVCC PostgreSQL ,
UPDATE
sarana untuk membuat versi baris baru dan menandai yang lama sebagai dihapus. Itu tentang semahalINSERT
danDELETE
gabungan. Plus, itu membuat Anda dengan banyak tupel mati. Karena Anda memperbarui seluruh tabel, bagaimanapun, akan lebih cepat secara keseluruhan untuk hanya membuat tabel baru dan menjatuhkan yang lama.Jika Anda memiliki cukup RAM, atur
temp_buffers
(hanya untuk sesi ini!) Cukup tinggi untuk menampung tabel temp di RAM - sebelum Anda melakukan hal lain.Untuk mendapatkan perkiraan berapa banyak RAM yang dibutuhkan, jalankan tes dengan sampel kecil dan gunakan fungsi ukuran objek db :
Script lengkap
Beban serentak
Operasi bersamaan di atas meja (yang saya singkirkan dalam asumsi di awal) akan menunggu, setelah meja dikunci di dekat akhir dan gagal segera setelah transaksi dilakukan, karena nama tabel diselesaikan untuk OID segera, tetapi tabel baru memiliki OID yang berbeda. Tabel tetap konsisten, tetapi operasi bersamaan dapat memperoleh pengecualian dan harus diulang. Detail dalam jawaban terkait ini:
Rute UPDATE
Jika Anda (harus) pergi
UPDATE
rute, jatuhkan indeks apa pun yang tidak diperlukan selama pembaruan dan buat kembali sesudahnya. Jauh lebih murah untuk membuat indeks dalam keadaan utuh daripada memperbaruinya untuk setiap baris. Ini juga memungkinkan pembaruan HOT .Saya menguraikan prosedur serupa menggunakan
UPDATE
dalam jawaban terkait erat pada SO .sumber
DROP TABLE
mengeluarkan sebuahAccess Exclusive Lock
. Either way, saya sudah mendaftar prasyarat di bagian atas jawaban saya:You can afford to drop and recreate the target table.
Mungkin membantu untuk mengunci meja pada awal transaksi. Saya sarankan Anda memulai pertanyaan baru dengan semua perincian yang relevan dengan situasi Anda sehingga kami dapat menyelesaikan ini.CREATE TABLE tbl_new AS SELECT t.*, u.field1, u.field2 from tbl t NATURAL LEFT JOIN tmp_tbl u;
,LEFT JOIN
memungkinkan untuk menjaga baris yang tidak ada pembaruan. Tentu sajaNATURAL
dapat diubah menjadi apa pun yang validUSING()
atauON
.Jika data dapat tersedia dalam file terstruktur Anda bisa membacanya dengan pembungkus data asing dan melakukan penggabungan pada tabel target.
sumber
MERGE
belum diimplementasikan dalam PostgreSQL (belum). Implementasi dalam RDBMS lain sedikit berbeda. Pertimbangkan info tag untukMERGE
danUPSERT
.