sql >> Database >  >> RDS >> PostgreSQL

Langzame eenvoudige update-query op PostgreSQL-database met 3 miljoen rijen

Ik moet tabellen van 1 of 2 miljard rijen bijwerken met verschillende waarden voor elke rij. Elke run maakt ~ 100 miljoen wijzigingen (10%). Mijn eerste poging was om ze te groeperen in transactie van 300K-updates rechtstreeks op een specifieke partitie, aangezien Postgresql voorbereide query's niet altijd optimaliseert als u partities gebruikt.

  1. Transacties van een heleboel "UPDATE myTable SET myField=value WHEREmyId=id"
    Geeft 1500 updates/sec. wat betekent dat elke run minstens 18 uur zou duren.
  2. HOT werkt de oplossing bij zoals hier beschreven met FILLFACTOR=50. Geeft 1600 updates/sec. Ik gebruik SSD's, dus het is een kostbare verbetering omdat het de opslagcapaciteit verdubbelt.
  3. Voeg toe aan een tijdelijke tabel met bijgewerkte waarde en voeg ze daarna samen met UPDATE...FROM Geeft 18.000 updates/sec. als ik een VACUUM doe voor elke partitie; 100.000 up/s anders. Cooool.
    Dit is de volgorde van bewerkingen:
CREATE TEMP TABLE tempTable (id BIGINT NOT NULL, field(s) to be updated,
CONSTRAINT tempTable_pkey PRIMARY KEY (id));

Verzamel een heleboel updates in een buffer, afhankelijk van het beschikbare RAM-geheugen. Wanneer het is gevuld, of van tabel/partitie moet worden gewijzigd, of voltooid:

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;

Dat betekent dat een run nu 1,5 uur duurt in plaats van 18 uur voor 100 miljoen updates, inclusief vacuüm. Om tijd te besparen, is het niet nodig om aan het eind een vacuüm VOL te maken, maar zelfs een snelle, regelmatige vacuüm is handig om uw transactie-ID in de database te controleren en geen ongewenste autovacuüm tijdens de spits te krijgen.



  1. 5 Tekenen dat je Excel bent ontgroeid

  2. Innerlijke join &outer join; is de volgorde van tabellen in van belangrijk?

  3. Hoe iif() werkt in SQLite

  4. Verschil tussen inline en out-of-line beperkingen