it-swarm-eu.dev

Nejúčinnější způsob přidání sériového sloupce k obrovské tabulce

Jaký je nejrychlejší způsob, jak přidat BIGSERIAL sloupec do obrovské tabulky (~ 3 Bil. Řádky, ~ 174Gb)?

UPRAVIT:

  • Chci sloupec zvýšit hodnoty pro existující řádky (NOT NULL).
  • Nenastavil jsem fillfactor (což vypadá jako špatné rozhodnutí v retrospektivě).
  • Nemám problém s diskovým prostorem, jen chci, aby to bylo co nejrychlejší.
10
Thi Duong Nguyen

Co je špatného:

ALTER TABLE foo ADD column bar bigserial;

Automaticky se naplní jedinečnými hodnotami (počínaje 1).

Pokud chcete číslo pro každý existující řádek, musí být aktualizován každý řádek v tabulce . Nebo ne?

Tabulka nemůže být nafouknuta na dvojnásobek své velikosti, pokud nemůže znovu použít mrtvé n-tice nebo volné místo na datových stránkách. Výkon operace by mohl hodně prospět z FILLFACTOR nižších než 100 nebo z náhodných mrtvých vrhů rozložených po stole. Jinak možná budete chtít spustit VACUUM FULL ANALYZE A získat tak místo na disku. To však nebude rychlé.

pgstattuple
Toto rozšíření by vás mohlo zajímat. Pomáhá vám shromažďovat statistiky o vašich stolech. Chcete-li zjistit více o mrtvých tuplech a volném prostoru:

Nainstalujte rozšíření jednou na databázi:

CREATE EXTENSION pgstattuple;

Volání:

SELECT * FROM pgstattuple('tbl');

Alternativní

Pokud si můžete dovolit vytvořit novou tabulku, která by zlomila závislé pohledy, cizí klíče, ...

Vytvořte prázdnou kopii staré tabulky:

CREATE new_tbl AS
SELECT *
FROM   old_tbl
LIMIT  0;

Přidejte velký sloupec:

ALTER new_tbl ADD column bar bigserial;

VLOŽTE data ze staré tabulky a automaticky vyplňte bigserial:

INSERT INTO new_tbl
SELECT *    --  new column will be filled with default
FROM   old_tbl
ORDER  BY something; -- or don't order if you don't care: faster

Nový sloupec velkého rozsahu chybí ve VÝBĚRU INSERTU a bude vyplněn automaticky výchozí hodnoto . Můžete hláskovat všechny sloupce a přidat nextval() do seznamu SELECT se stejným efektem.

Ujistěte se, že máte všechna data v nové tabulce.
Přidejte indexy, omezení, spouštěče, které jste měli ve staré tabulce nyní.

DROP TABLE old_tbl;
ALTER TABLE new_tbl RENAME TO old_tbl;

Může to být celkem o něco rychlejší. To vám dává vanilkovou tabulku (a indexy) bez nadýmání.

Potřebujete volné místo na disku - kolem velikosti staré tabulky, v závislosti na stavu tabulky - jako kroutící místnost. Ale s první jednoduchou metodou budete možná potřebovat tolik kvůli tabulkovému nadýmání. Podrobnosti opět závisí na stavu vaší tabulky.

12