Saya bertanya-tanya apa cara paling efisien untuk menghapus sejumlah besar baris dari PostgreSQL, proses ini akan menjadi bagian dari tugas berulang setiap hari untuk mengimpor data massal (delta penyisipan + penghapusan) ke dalam tabel. Mungkin ada ribuan, berpotensi jutaan baris untuk dihapus.
Saya punya file kunci utama, satu per baris. Dua opsi yang saya pikirkan ada di sepanjang baris di bawah ini, tapi saya tidak tahu / cukup memahami internal PostgreSQL untuk membuat keputusan yang tepat.
- Jalankan
DELETE
kueri untuk setiap baris dalam file, dengan sederhanaWHERE
pada kunci utama (atau kelompokkan penghapusan dalam batchn
menggunakanIN()
klausa) - Impor kunci utama ke tabel sementara menggunakan
COPY
perintah dan kemudian hapus dari tabel utama menggunakan gabungan
Setiap saran akan sangat dihargai!
postgresql
delete
bulk
tarnfeld
sumber
sumber
Jawaban:
Pilihan kedua Anda jauh lebih bersih dan berkinerja cukup baik untuk membuatnya layak. Alternatif Anda adalah membuat pertanyaan raksasa yang akan cukup menyakitkan untuk direncanakan dan dijalankan. Secara umum Anda akan lebih baik membiarkan PostgreSQL melakukan pekerjaan di sini. Secara umum, saya telah menemukan pembaruan pada puluhan ribu baris dengan cara yang Anda jelaskan berkinerja memadai, tetapi ada satu hal penting yang harus dihindari.
Cara melakukannya adalah dengan menggunakan pilih dan bergabung dalam penghapusan Anda.
Dalam situasi apa pun Anda harus mengikuti tabel besar:
Ini biasanya akan menyebabkan antijoin loop bersarang yang akan membuat kinerja agak bermasalah. Jika Anda akhirnya harus menempuh rute itu, lakukan ini sebagai gantinya:
PostgreSQL biasanya cukup baik dalam menghindari rencana yang buruk tetapi masih ada kasus yang melibatkan gabungan luar yang dapat membuat perbedaan besar antara rencana yang baik dan yang buruk.
Ini mengembara sedikit lebih jauh, tapi saya pikir itu layak disebutkan karena betapa mudahnya untuk beralih dari IN ke NOT IN dan menonton tangki kinerja permintaan.
sumber
IN ( select id from foo except select id from rows_to_keep )
lihat postgresql.org/docs/9.4/static/queries-union.htmlSaya menemukan pertanyaan ini karena saya memiliki masalah yang sama. Saya membersihkan database yang memiliki 300M + baris, database akhir hanya akan memiliki sekitar 30% dari data asli. Jika Anda menghadapi skenario yang sama, sebenarnya lebih mudah untuk memasukkan tabel baru dan mengindeks ulang daripada menghapus.
Lakukan sesuatu seperti
Dengan pengindeksan yang tepat di foo dan bar, Anda dapat menghindari pemindaian Seq.
Maka Anda harus mengindeks ulang dan mengganti nama tabel.
sumber