Vše závisí na ...
-
Za předpokladu žádného souběžného přístupu pro zápis k zapojeným stolům nebo možná budete muset zamykat výhradně stoly nebo tato cesta nemusí být vůbec pro vás.
-
Smažte všechny indexy (možná kromě těch, které jsou potřebné pro samotné smazání).
Potom je znovu vytvořte. To je obvykle mnohem rychlejší než přírůstkové aktualizace indexů. -
Zkontrolujte, zda máte spouštěče, které lze bezpečně smazat / dočasně deaktivovat.
-
Odkazují cizí klíče na vaši tabulku? Lze je smazat? Dočasně smazáno?
-
V závislosti na nastavení automatického vysávání může pomůže spustit
VACUUM ANALYZE
před operací. -
Některé z bodů uvedených v související kapitole příručky Naplnění databáze může být také užitečné, v závislosti na vašem nastavení.
-
Pokud odstraníte velké části tabulky a zbytek se vejde do paměti RAM, nejrychlejší a nejjednodušší způsob může být tento:
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;
Tímto způsobem nemusíte znovu vytvářet pohledy, cizí klíče nebo jiné závislé objekty. A získáte nedotčený (tříděný) stůl bez nadýmání.
Přečtěte si o temp_buffers
nastavení v návodu. Tato metoda je rychlá, pokud se tabulka vejde do paměti, nebo alespoň její většiny. Transakční obal chrání před ztrátou dat, pokud váš server selže uprostřed této operace.
Spusťte VACUUM ANALYZE
později. Nebo VACUUM FULL ANALYZE
pokud jej chcete snížit na minimální velikost (využívá exkluzivní zámek). Pro velké tabulky zvažte alternativy CLUSTER
/ pg_repack
nebo podobně:
- Optimalizujte rozsah dotazu časového razítka Postgres
Pro malé tabulky stačí jednoduchý DELETE
místo TRUNCATE
je často rychlejší:
DELETE FROM tbl t
USING del_list d
WHERE t.id = d.id;
Přečíst Poznámky sekce pro TRUNCATE
v návodu. Zejména (jak ve svém komentáři zdůraznil i Pedro):
TRUNCATE
nelze použít u tabulky, která má odkazy na cizí klíč z jiných tabulek, pokud nejsou všechny takové tabulky také zkráceny ve stejném příkazu. [...]
A:
TRUNCATE
nespustí žádnéON DELETE
spouštěče, které mohou pro tabulky existovat.