PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Query di aggiornamento semplice e lenta sul database PostgreSQL con 3 milioni di righe

Devo aggiornare tabelle di 1 o 2 miliardi di righe con vari valori per ogni riga. Ogni esecuzione apporta circa 100 milioni di modifiche (10%). Il mio primo tentativo è stato di raggrupparli in una transazione di 300.000 aggiornamenti direttamente su una partizione specifica poiché Postgresql non sempre ottimizza le query preparate se si utilizzano le partizioni.

  1. Transazioni del gruppo di "UPDATE myTable SET myField=value WHEREmyId=id"
    Fornisce 1.500 aggiornamenti/sec. il che significa che ogni corsa richiederebbe almeno 18 ore.
  2. La soluzione HOT aggiorna come descritto qui con FILLFACTOR=50. Fornisce 1.600 aggiornamenti/sec. Uso gli SSD, quindi è un miglioramento costoso in quanto raddoppia le dimensioni dello spazio di archiviazione.
  3. Inserisci in una tabella temporanea di valore aggiornato e uniscili dopo con UPDATE...FROM Fornisce 18.000 aggiornamenti/sec. se faccio un VACUUM per ogni partizione; 100.000 in su/s altrimenti. Cooool.
    Ecco la sequenza delle operazioni:
CREATE TEMP TABLE tempTable (id BIGINT NOT NULL, field(s) to be updated,
CONSTRAINT tempTable_pkey PRIMARY KEY (id));

Accumula un sacco di aggiornamenti in un buffer a seconda della RAM disponibile Quando è pieno, devi cambiare tabella/partizione o completato:

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;

Ciò significa che una corsa ora richiede 1,5 ore invece di 18 ore per 100 milioni di aggiornamenti, vuoto incluso. Per risparmiare tempo, non è necessario eseguire un'aspirazione PIENA alla fine, ma anche un'aspirazione veloce e regolare è utile per controllare l'ID della transazione sul database e non ottenere un'aspirazione automatica indesiderata durante le ore di punta.