Lihat mengisi database di manual PostgreSQL, artikel depesz yang sangat baik seperti biasa tentang topik tersebut, dan pertanyaan SO ini.
(Perhatikan bahwa jawaban ini adalah tentang memuat data secara massal ke dalam DB yang ada atau untuk membuat yang baru. Jika Anda tertarik, DB memulihkan kinerja dengan pg_restore
atau psql
eksekusi pg_dump
keluaran, banyak dari ini tidak berlaku karena pg_dump
dan pg_restore
sudah melakukan hal-hal seperti membuat pemicu dan indeks setelah menyelesaikan skema+pemulihan data) .
Ada banyak yang harus dilakukan. Solusi ideal adalah mengimpor ke UNLOGGED
tabel tanpa indeks, lalu ubah menjadi login dan tambahkan indeks. Sayangnya di PostgreSQL 9.4 tidak ada dukungan untuk mengubah tabel dari UNLOGGED
untuk login. 9.5 menambahkan ALTER TABLE ... SET LOGGED
untuk mengizinkan Anda melakukan ini.
Jika Anda dapat membuat database offline untuk impor massal, gunakan pg_bulkload
.
Jika tidak:
-
Nonaktifkan pemicu apa pun di atas meja
-
Jatuhkan indeks sebelum memulai impor, buat kembali setelahnya. (Dibutuhkan banyak lebih sedikit waktu untuk membangun indeks dalam satu lintasan daripada menambahkan data yang sama ke dalamnya secara bertahap, dan indeks yang dihasilkan jauh lebih ringkas).
-
Jika melakukan impor dalam satu transaksi, aman untuk menghapus batasan kunci asing, melakukan impor, dan membuat ulang batasan sebelum melakukan. Jangan lakukan ini jika impor dibagi menjadi beberapa transaksi karena Anda dapat memasukkan data yang tidak valid.
-
Jika memungkinkan, gunakan
COPY
bukannyaINSERT
s -
Jika Anda tidak dapat menggunakan
COPY
pertimbangkan untuk menggunakan multi-nilaiINSERT
s jika praktis. Anda sepertinya sudah melakukan ini. Jangan coba daftar juga banyak nilai dalam satuVALUES
meskipun; nilai-nilai itu harus muat dalam memori beberapa kali, jadi pertahankan beberapa ratus per pernyataan. -
Batch sisipan Anda ke dalam transaksi eksplisit, melakukan ratusan ribu atau jutaan sisipan per transaksi. Tidak ada batasan praktis AFAIK, tetapi batching akan memungkinkan Anda memulihkan dari kesalahan dengan menandai awal setiap batch dalam data input Anda. Sekali lagi, Anda sepertinya sudah melakukan ini.
-
Gunakan
synchronous_commit=off
dancommit_delay
huge yang besar untuk mengurangi biaya fsync(). Ini tidak akan banyak membantu jika Anda telah mengelompokkan pekerjaan Anda menjadi transaksi besar. -
INSERT
atauCOPY
secara paralel dari beberapa koneksi. Berapa banyak tergantung pada subsistem disk perangkat keras Anda; sebagai aturan praktis, Anda menginginkan satu koneksi per hard drive fisik jika menggunakan penyimpanan yang terpasang langsung. -
Setel
max_wal_size
tinggi nilai (checkpoint_segments
di versi yang lebih lama) dan aktifkanlog_checkpoints
. Lihat log PostgreSQL dan pastikan itu tidak mengeluh tentang pos pemeriksaan yang terjadi terlalu sering. -
Jika dan hanya jika Anda tidak keberatan kehilangan seluruh klaster PostgreSQL (database Anda dan yang lainnya di klaster yang sama) karena kerusakan besar jika sistem mogok selama impor, Anda dapat menghentikan Pg, setel
fsync=off
, mulai Pg, lakukan impor Anda, lalu (sangat penting) hentikan Pg dan aturfsync=on
lagi. Lihat konfigurasi WAL. Jangan lakukan ini jika sudah ada data yang Anda pedulikan di database mana pun di instalasi PostgreSQL Anda. Jika Anda menyetelfsync=off
Anda juga dapat mengaturfull_page_writes=off
; sekali lagi, ingatlah untuk mengaktifkannya kembali setelah Anda mengimpor untuk mencegah kerusakan database dan kehilangan data. Lihat pengaturan yang tidak tahan lama di manual Pg.
Anda juga harus melihat penyetelan sistem Anda:
-
Gunakan kualitas bagus SSD untuk penyimpanan sebanyak mungkin. SSD yang bagus dengan cache write-back yang andal dan terlindungi daya membuat kecepatan commit menjadi lebih cepat. Mereka kurang bermanfaat bila Anda mengikuti saran di atas - yang mengurangi penggelontoran disk / jumlah
fsync()
s - tapi masih bisa sangat membantu. Jangan gunakan SSD murah tanpa perlindungan kegagalan daya yang tepat kecuali Anda tidak peduli dengan penyimpanan data Anda. -
Jika Anda menggunakan RAID 5 atau RAID 6 untuk penyimpanan terpasang langsung, hentikan sekarang. Cadangkan data Anda, atur ulang susunan RAID Anda ke RAID 10, dan coba lagi. RAID 5/6 tidak ada harapan untuk kinerja penulisan massal - meskipun pengontrol RAID yang baik dengan cache besar dapat membantu.
-
Jika Anda memiliki opsi untuk menggunakan pengontrol RAID perangkat keras dengan cache tulis kembali yang didukung baterai besar, ini benar-benar dapat meningkatkan kinerja penulisan untuk beban kerja dengan banyak komitmen. Ini tidak banyak membantu jika Anda menggunakan komit asinkron dengan commit_delay atau jika Anda melakukan lebih sedikit transaksi besar selama pemuatan massal.
-
Jika memungkinkan, simpan WAL (
pg_wal
, ataupg_xlog
dalam versi lama) pada disk / array disk yang terpisah. Tidak ada gunanya menggunakan sistem file terpisah pada disk yang sama. Orang sering memilih untuk menggunakan pasangan RAID1 untuk WAL. Sekali lagi, ini memiliki lebih banyak efek pada sistem dengan tingkat komit tinggi, dan efeknya kecil jika Anda menggunakan tabel yang tidak dicatat sebagai target pemuatan data.
Anda mungkin juga tertarik dengan Optimalkan PostgreSQL untuk pengujian cepat.