Musím aktualizovat tabulky s 1 nebo 2 miliardami řádků s různými hodnotami pro každý řádek. Každé spuštění provede ~ 100 milionů změn (10 %). Můj první pokus byl seskupit je do transakce 300 000 aktualizací přímo na konkrétním oddílu, protože Postgresql ne vždy optimalizuje připravené dotazy, pokud používáte oddíly.
- Transakce skupiny "UPDATE myTable SET myField=value WHEREmyId=id"
dává 1 500 aktualizace/sec. což znamená, že každý běh by trval nejméně 18 hodin. - Řešení HOT aktualizací, jak je popsáno zde, s FILLFACTOR=50. Poskytuje 1 600 aktualizací/s. Používám SSD, takže je to nákladné vylepšení, protože zdvojnásobuje velikost úložiště.
- Vložit do dočasné tabulky aktualizované hodnoty a poté je sloučit s UPDATE...FROM dává 18 000 aktualizace/sec. když udělám VACUUM pro každý oddíl; 100 000 nahoru/s jinak. Cooool.
Zde je sekvence operací:
CREATE TEMP TABLE tempTable (id BIGINT NOT NULL, field(s) to be updated,
CONSTRAINT tempTable_pkey PRIMARY KEY (id));
Nashromáždit spoustu aktualizací ve vyrovnávací paměti v závislosti na dostupné paměti RAM, když je zaplněna nebo je potřeba změnit tabulku/oddíl nebo je dokončena:
COPY tempTable FROM buffer;
UPDATE myTable a SET field(s)=value(s) FROM tempTable b WHERE a.id=b.id;
COMMIT;
TRUNCATE TABLE tempTable;
VACUUM FULL ANALYZE myTable;
To znamená, že běh nyní trvá 1,5 hodiny místo 18 hodin pro 100 milionů aktualizací, včetně vakua. Abyste ušetřili čas, není nutné na konci provádět vakuum PLNÉ, ale i rychlé pravidelné vakuování je užitečné pro kontrolu vašeho ID transakce v databázi a nedochází k nechtěnému automatickému vakuu během dopravní špičky.