sql >> Databáze >  >> RDS >> PostgreSQL

Nejlepší způsob, jak odstranit miliony řádků podle ID

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.



  1. Top 5 bezplatných nástrojů pro návrh databáze

  2. Připojení JDBC se nezdařilo, chyba:Připojení TCP/IP k hostiteli selhalo

  3. Nejlepší způsob, jak zkontrolovat prázdnou nebo nulovou hodnotu

  4. Jak zašifrovat uloženou proceduru na serveru SQL Server