Tutto dipende...
-
Presupponendo nessun accesso in scrittura simultaneo ai tavoli coinvolti o potresti dover bloccare esclusivamente i tavoli o questo percorso potrebbe non essere adatto a te.
-
Elimina tutti gli indici (possibilmente tranne quelli necessari per l'eliminazione stessa).
Ricreali in seguito. In genere è molto più veloce degli aggiornamenti incrementali degli indici. -
Verifica se disponi di trigger che possono essere eliminati/disabilitati temporaneamente in sicurezza.
-
Le chiavi esterne fanno riferimento alla tua tabella? Si possono eliminare? Eliminato temporaneamente?
-
A seconda delle impostazioni dell'autovuoto, potrebbe aiuto per eseguire
VACUUM ANALYZE
prima dell'operazione. -
Alcuni dei punti elencati nel relativo capitolo del manuale Popolare un Database potrebbe anche essere utile, a seconda della configurazione.
-
Se elimini grandi porzioni della tabella e il resto si inserisce nella RAM, il modo più semplice e veloce potrebbe essere questo:
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;
In questo modo non è necessario ricreare viste, chiavi esterne o altri oggetti dipendenti. E ottieni un tavolo incontaminato (ordinato) senza gonfiarsi.
Leggi i temp_buffers
impostazione nel manuale. Questo metodo è veloce fintanto che la tabella si adatta alla memoria, o almeno la maggior parte di essa. Il wrapper delle transazioni protegge dalla perdita di dati se il tuo server si arresta in modo anomalo durante questa operazione.
Esegui VACUUM ANALYZE
dopo. Oppure VACUUM FULL ANALYZE
se vuoi portarlo alla dimensione minima (prende il blocco esclusivo). Per i tavoli grandi considera le alternative CLUSTER
/ pg_repack
o simili:
- Ottimizza l'intervallo di query del timestamp di Postgres
Per i tavolini, un semplice DELETE
invece di TRUNCATE
è spesso più veloce:
DELETE FROM tbl t
USING del_list d
WHERE t.id = d.id;
Leggi le Note sezione per TRUNCATE
nel manuale. In particolare (come ha sottolineato anche Pedro nel suo commento):
TRUNCATE
non può essere utilizzato su una tabella che ha riferimenti a chiavi esterne da altre tabelle, a meno che anche tutte queste tabelle non vengano troncate nello stesso comando. [...]
E:
TRUNCATE
non attiverà alcun ON DELETE
trigger che potrebbero esistere per le tabelle.