Het hangt allemaal af ...
-
Ervan uitgaande dat geen gelijktijdige schrijftoegang naar betrokken tafels of misschien moet je de tafels exclusief vergrendelen of is deze route misschien helemaal niet voor jou.
-
Verwijder alle indexen (mogelijk behalve degene die nodig zijn voor het verwijderen zelf).
Maak ze daarna opnieuw aan. Dat is doorgaans veel sneller dan incrementele updates van indexen. -
Controleer of je triggers hebt die veilig tijdelijk kunnen worden verwijderd/uitgeschakeld.
-
Verwijzen buitenlandse sleutels naar uw tabel? Kunnen ze worden verwijderd? Tijdelijk verwijderd?
-
Afhankelijk van uw autovacuüminstellingen kan het mogelijk hulp bij het uitvoeren van
VACUUM ANALYZE
voor de operatie. -
Enkele van de punten die worden genoemd in het gerelateerde hoofdstuk van de handleiding Een database vullen kan ook nuttig zijn, afhankelijk van uw opstelling.
-
Als u grote delen van de tabel verwijdert en de rest past in het RAM-geheugen, is dit de snelste en gemakkelijkste manier:
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;
Op deze manier hoeft u geen weergaven, externe sleutels of andere afhankelijke objecten opnieuw te maken. En je krijgt een smetteloze (gesorteerde) tafel zonder opgeblazen gevoel.
Lees over de temp_buffers
instelling in de handleiding. Deze methode is snel zolang de tabel in het geheugen past, of in ieder geval het grootste deel ervan. De transactie-wrapper beschermt tegen gegevensverlies als uw server tijdens deze bewerking crasht.
Voer VACUUM ANALYZE
uit daarna. Of VACUUM FULL ANALYZE
als je het naar de minimale grootte wilt brengen (neemt exclusief slot op). Overweeg voor grote tafels de alternatieven CLUSTER
/ pg_repack
of vergelijkbaar:
- Optimaliseer het zoekopdrachtbereik van Postgres-tijdstempel
Voor kleine tabellen, een simpele DELETE
in plaats van TRUNCATE
is vaak sneller:
DELETE FROM tbl t
USING del_list d
WHERE t.id = d.id;
Lees de Opmerkingen sectie voor TRUNCATE
in de handleiding. In het bijzonder (zoals Pedro ook opmerkte in zijn commentaar):
TRUNCATE
kan niet worden gebruikt op een tabel die refererende-sleutelverwijzingen heeft uit andere tabellen, tenzij al dergelijke tabellen ook worden afgekapt in dezelfde opdracht. [...]
En:
TRUNCATE
zal geenON DELETE
fire afvuren triggers die kunnen bestaan voor de tabellen.