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.