PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Najlepszy sposób na usunięcie milionów wierszy według identyfikatora

Wszystko zależy...

  • Zakładając brak równoczesnego dostępu do zapisu do zaangażowanych tabel lub być może będziesz musiał zablokować wyłącznie tabele lub ta trasa może wcale nie być dla Ciebie.

  • Usuń wszystkie indeksy (prawdopodobnie z wyjątkiem tych potrzebnych do samego usunięcia).
    Utwórz je później. Zwykle jest to znacznie szybsze niż przyrostowe aktualizacje indeksów.

  • Sprawdź, czy masz wyzwalacze, które można bezpiecznie usunąć / tymczasowo wyłączyć.

  • Czy klucze obce odwołują się do Twojej tabeli? Czy można je usunąć? Tymczasowo usunięte?

  • W zależności od ustawień automatycznego odkurzania może pomoc w uruchomieniu VACUUM ANALYZE przed operacją.

  • Niektóre z punktów wymienionych w odpowiednim rozdziale podręcznika Wypełnianie bazy danych może być również przydatny, w zależności od konfiguracji.

  • Jeśli usuniesz duże części tabeli, a reszta zmieści się w pamięci RAM, najszybszy i najłatwiejszy sposób może być następujący:

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;

W ten sposób nie musisz odtwarzać widoków, kluczy obcych lub innych zależnych obiektów. I otrzymujesz nieskazitelny (posortowany) stół bez wzdęć.

Przeczytaj o temp_buffers ustawienie w instrukcji. Ta metoda jest szybka, o ile tabela mieści się w pamięci, a przynajmniej w większości. Opakowanie transakcji chroni przed utratą danych, jeśli serwer ulegnie awarii w trakcie tej operacji.

Uruchom VACUUM ANALYZE następnie. Lub VACUUM FULL ANALYZE jeśli chcesz sprowadzić go do minimalnego rozmiaru (zajmuje ekskluzywny zamek). W przypadku dużych tabel rozważ alternatywy CLUSTER / pg_repack lub podobny:

  • Optymalizuj zakres zapytań sygnatury czasowej Postgres

W przypadku małych tabel, proste DELETE zamiast TRUNCATE jest często szybszy:

DELETE FROM tbl t
USING  del_list d
WHERE  t.id = d.id;

Czytaj Notatki sekcja dla TRUNCATE w instrukcji. W szczególności (jak zauważył Pedro w swoim komentarzu):

TRUNCATE nie można użyć w tabeli, która ma odniesienia do kluczy obcych z innych tabel, chyba że wszystkie takie tabele są również obcinane w tym samym poleceniu. [...]

Oraz:

TRUNCATE nie uruchomi żadnego ON DELETE wyzwalacze, które mogą istnieć dla 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. Jak uzyskać aktualną datę i godzinę (bez strefy czasowej) w PostgreSQL?

  2. Zrzut Postgres zawierający tylko części tabel dla migawki dewelopera

  3. Odpowiednik DATEADD w PostgreSQL

  4. 2 sposoby na uzyskanie rozmiaru bazy danych w PostgreSQL

  5. Jak przenieść moją istniejącą aplikację rails na heroku? (sqlite do postgresa)