Tout dépend...
-
En supposant aucun accès en écriture simultané aux tables impliquées ou vous devrez peut-être verrouiller les tables exclusivement ou cet itinéraire peut ne pas vous convenir du tout.
-
Supprimez tous les index (éventuellement sauf ceux nécessaires à la suppression elle-même).
Recréez-les ensuite. C'est généralement beaucoup plus rapide que les mises à jour incrémentielles des index. -
Vérifiez si vous avez des déclencheurs qui peuvent être supprimés/désactivés temporairement en toute sécurité.
-
Les clés étrangères référencent-elles votre table ? Peuvent-ils être supprimés ? Temporairement supprimé ?
-
En fonction de vos paramètres de vide automatique, il peut aide pour exécuter
VACUUM ANALYZE
avant l'opération. -
Certains des points listés dans le chapitre correspondant du manuel Remplir une base de données peut également être utile, selon votre configuration.
-
Si vous supprimez de grandes parties du tableau et que le reste tient dans la RAM, le moyen le plus rapide et le plus simple peut être celui-ci :
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;
De cette façon, vous n'avez pas à recréer des vues, des clés étrangères ou d'autres objets dépendants. Et vous obtenez une table vierge (triée) sans ballonnement.
En savoir plus sur les temp_buffers
réglage dans le manuel. Cette méthode est rapide tant que la table tient dans la mémoire, ou du moins la plus grande partie. Le wrapper de transaction protège contre la perte de données si votre serveur tombe en panne au milieu de cette opération.
Exécutez VACUUM ANALYZE
ensuite. Ou VACUUM FULL ANALYZE
si vous voulez l'amener à la taille minimale (prend un verrou exclusif). Pour les grandes tables, considérez les alternatives CLUSTER
/ pg_repack
ou similaire :
- Optimiser la plage de requêtes d'horodatage Postgres
Pour les petits tableaux, un simple DELETE
au lieu de TRUNCATE
est souvent plus rapide :
DELETE FROM tbl t
USING del_list d
WHERE t.id = d.id;
Lire les Remarques section pour TRUNCATE
dans le manuel. En particulier (comme Pedro l'a également souligné dans son commentaire) :
TRUNCATE
ne peut pas être utilisé sur une table contenant des références de clé étrangère provenant d'autres tables, à moins que toutes ces tables ne soient également tronquées dans la même commande. [...]
Et :
TRUNCATE
ne déclenchera aucunON DELETE
déclencheurs qui pourraient exister pour les tables.