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

Cara terbaik untuk menghapus jutaan baris dengan ID

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 memecat ON DELETE pemicu yang mungkin ada untuk tabel.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Mendapatkan hasil antara dua tanggal di PostgreSQL

  2. PostgreSQL:serial vs identitas

  3. Cara terbaik untuk memeriksa nilai kosong atau nol

  4. Bagaimana saya harus mengimpor data dari CSV ke tabel Postgres menggunakan pgAdmin 3?

  5. Postgres menyalin DB Produksi Heroku ke DB pengembangan lokal