PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Cara mempercepat kinerja penyisipan di PostgreSQL

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 bukannya INSERT s

  • Jika Anda tidak dapat menggunakan COPY pertimbangkan untuk menggunakan multi-nilai INSERT s jika praktis. Anda sepertinya sudah melakukan ini. Jangan coba daftar juga banyak nilai dalam satu VALUES 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 dan commit_delay huge yang besar untuk mengurangi biaya fsync(). Ini tidak akan banyak membantu jika Anda telah mengelompokkan pekerjaan Anda menjadi transaksi besar.

  • INSERT atau COPY 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 aktifkan log_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 atur fsync=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 menyetel fsync=off Anda juga dapat mengatur full_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 , atau pg_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.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. instalasi postgres inisialisasi cluster database gagal ( Postgresql Versi 9.4.4 )

  2. Format tanggal UTC Postgres &pemeran zaman, tanda inversi

  3. Bagaimana Anda membuat PyPy, Django dan PostgreSQL bekerja bersama?

  4. String -> java.util.Date -> java.sql.Date (dengan cap waktu)

  5. Bagaimana cara mengubah pemformatan untuk nilai yang saya kembalikan dalam fungsi ini?