Itu semua tergantung ...
-
Dengan asumsi tidak ada akses tulis bersamaan ke tabel yang terlibat atau Anda mungkin harus mengunci tabel secara eksklusif atau rute ini mungkin tidak cocok untuk Anda sama sekali.
-
Hapus semua indeks (mungkin kecuali yang diperlukan untuk penghapusan itu sendiri).
Buat ulang setelahnya. Itu biasanya jauh lebih cepat daripada pembaruan inkremental untuk indeks. -
Periksa apakah Anda memiliki pemicu yang dapat dihapus/dinonaktifkan sementara dengan aman.
-
Apakah kunci asing mereferensikan tabel Anda? Bisakah mereka dihapus? Dihapus sementara?
-
Tergantung pada pengaturan autovacuum Anda, itu mungkin bantuan untuk menjalankan
VACUUM ANALYZE
sebelum operasi. -
Beberapa poin yang tercantum dalam bab terkait dari manual Mengisi Database mungkin juga berguna, tergantung pada penyiapan Anda.
-
Jika Anda menghapus sebagian besar tabel dan sisanya masuk ke dalam RAM, cara tercepat dan termudah adalah ini:
BEGIN; -- typically faster and safer wrapped in a single transaction
SET LOCAL temp_buffers = '1000MB'; -- enough to hold the temp table
CREATE TEMP TABLE tmp AS
SELECT t.*
FROM tbl t
LEFT JOIN del_list d USING (id)
WHERE d.id IS NULL; -- copy surviving rows into temporary table
TRUNCATE tbl; -- empty table - truncate is very fast for big tables
INSERT INTO tbl
SELECT * FROM tmp; -- insert back surviving rows.
-- ORDER BY ? -- optionally order favorably while being at it
COMMIT;
Dengan cara ini Anda tidak perlu membuat ulang tampilan, kunci asing, atau objek bergantung lainnya. Dan Anda mendapatkan meja yang murni (diurutkan) tanpa mengasapi.
Baca tentang temp_buffers
pengaturan dalam manual. Metode ini cepat selama tabel cocok dengan memori, atau setidaknya sebagian besar. Pembungkus transaksi melindungi dari kehilangan data jika server Anda mogok di tengah operasi ini.
Jalankan VACUUM ANALYZE
setelah itu. Atau VACUUM FULL ANALYZE
jika Anda ingin membawanya ke ukuran minimum (mengambil kunci eksklusif). Untuk tabel besar, pertimbangkan alternatif CLUSTER
/ pg_repack
atau serupa:
- Optimalkan rentang kueri cap waktu Postgres
Untuk tabel kecil, cukup DELETE
bukannya TRUNCATE
seringkali lebih cepat:
DELETE FROM tbl t
USING del_list d
WHERE t.id = d.id;
Baca Catatan bagian untuk TRUNCATE
dalam manual. Secara khusus (seperti yang juga ditunjukkan Pedro dalam komentarnya):
TRUNCATE
tidak dapat digunakan pada tabel yang memiliki referensi kunci asing dari tabel lain, kecuali semua tabel tersebut juga dipotong dalam perintah yang sama. [...]
Dan:
TRUNCATE
tidak akan memecatON DELETE
pemicu yang mungkin ada untuk tabel.