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

Pomalý jednoduchý aktualizační dotaz na databázi PostgreSQL s 3 miliony řádků

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.

  1. 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.
  2. Ř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ě.
  3. 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.



  1. Monitorování distribuce Percona pro PostgreSQL – klíčové metriky

  2. Blokovat, blokovat, blokovat na dveřích DBA s blokováním serveru SQL

  3. Jak převést řetězec na datum v PostgreSQL

  4. Chyba při načítání modulu MySQLdb 'Nainstalovali jste mysqlclient nebo MySQL-python?'