Ada sejumlah faktor yang bekerja di sini:
- Latensi jaringan dan penundaan pulang pergi
- Overhead per pernyataan di PostgreSQL
- Pengalih konteks dan penundaan penjadwal
COMMIT
biaya, jika untuk orang yang melakukan satu komit per sisipan (Anda tidak melakukannya)COPY
-pengoptimalan khusus untuk pemuatan massal
Latensi jaringan
Jika server jauh, Anda mungkin "membayar" "harga" waktu tetap per pernyataan, katakanlah, 50 ms (1/20 detik). Atau lebih banyak lagi untuk beberapa DB yang dihosting cloud. Karena penyisipan berikutnya tidak dapat dimulai hingga penyisipan terakhir berhasil diselesaikan, ini berarti maksimum your Anda tingkat penyisipan adalah 1000/pulang-perjalanan-latensi-dalam-ms baris per detik. Pada latensi 50 ms ("waktu ping"), itu 20 baris/detik. Bahkan di server lokal, penundaan ini tidak nol. Sedangkan COPY
hanya mengisi jendela pengiriman dan penerimaan TCP, dan mengalirkan baris secepat DB dapat menulisnya dan jaringan dapat mentransfernya. Itu tidak terlalu terpengaruh oleh latensi, dan mungkin menyisipkan ribuan baris per detik pada tautan jaringan yang sama.
Biaya per pernyataan di PostgreSQL
Ada juga biaya untuk menguraikan, merencanakan, dan mengeksekusi pernyataan di PostgreSQL. Itu harus mengambil kunci, membuka file relasi, mencari indeks, dll. COPY
mencoba melakukan semua ini sekali, di awal, lalu fokus saja memuat baris secepat mungkin.
Biaya pengalihan tugas/konteks
Ada biaya waktu lebih lanjut yang harus dibayar karena sistem operasi harus beralih antara postgres menunggu baris sementara aplikasi Anda mempersiapkan dan mengirimkannya, dan kemudian aplikasi Anda menunggu respons postgres saat postgres memproses baris. Setiap kali Anda beralih dari satu ke yang lain, Anda membuang sedikit waktu. Lebih banyak waktu berpotensi terbuang untuk menangguhkan dan melanjutkan berbagai status kernel tingkat rendah saat proses masuk dan keluar dari status menunggu.
Kehilangan pengoptimalan COPY
Selain itu, COPY
memiliki beberapa pengoptimalan yang dapat digunakan untuk beberapa jenis beban. Jika tidak ada kunci yang dihasilkan dan nilai default apa pun adalah konstanta, misalnya, ia dapat menghitungnya sebelumnya dan mengabaikan eksekutor sepenuhnya, memuat data dengan cepat ke dalam tabel di tingkat yang lebih rendah yang melewatkan sebagian dari pekerjaan normal PostgreSQL sepenuhnya. Jika Anda CREATE TABLE
atau TRUNCATE
dalam transaksi yang sama Anda COPY
, ia dapat melakukan lebih banyak trik untuk membuat pemuatan lebih cepat dengan mengabaikan pembukuan transaksi normal yang diperlukan dalam database multi-klien.
Meskipun demikian, COPY
Post PostgreSQL masih bisa melakukan lebih banyak untuk mempercepat, hal-hal yang belum tahu bagaimana melakukannya. Itu bisa secara otomatis melewati pembaruan indeks kemudian membangun kembali indeks jika Anda mengubah lebih dari proporsi tabel tertentu. Itu bisa melakukan pembaruan indeks dalam batch. Banyak lagi.
Biaya komit
Satu hal terakhir yang perlu dipertimbangkan adalah biaya komit. Ini mungkin bukan masalah bagi Anda karena psycopg2
default untuk membuka transaksi dan tidak melakukan sampai Anda menyuruhnya. Kecuali Anda menyuruhnya menggunakan autocommit. Tetapi untuk banyak driver DB, autocommit adalah default. Dalam kasus seperti itu, Anda akan melakukan satu komit untuk setiap INSERT
. Itu berarti satu disk flush, di mana server memastikan ia menulis semua data dalam memori ke disk dan memberitahu disk untuk menulis cache mereka sendiri ke penyimpanan persisten. Ini bisa memakan waktu lama waktu, dan sangat bervariasi berdasarkan perangkat keras. Laptop NVMe BTRFS saya yang berbasis SSD hanya dapat melakukan 200 fsyncs/detik, vs 300.000 penulisan/detik yang tidak disinkronkan. Jadi itu hanya akan memuat 200 baris/detik! Beberapa server hanya dapat melakukan 50 fsyncs/detik. Beberapa dapat melakukan 20.000. Jadi, jika Anda harus melakukan secara teratur, coba muat dan komit dalam batch, lakukan penyisipan multi-baris, dll. Karena COPY
hanya satu komit di akhir, biaya komit dapat diabaikan. Tapi ini juga berarti COPY
tidak dapat memulihkan dari kesalahan di tengah jalan melalui data; itu membatalkan seluruh beban massal.