Dal momento che stai unendo due tabelle di grandi dimensioni e non ci sono condizioni che potrebbero filtrare le righe, l'unica strategia di join efficiente sarà un hash join e nessun indice può aiutarti.
Per prima cosa ci sarà una scansione sequenziale di una delle tabelle, da cui viene costruita una struttura hash, quindi ci sarà una scansione sequenziale sull'altra tabella e l'hash verrà sondato per ogni riga trovata. In che modo un indice potrebbe essere d'aiuto in questo?
Puoi aspettarti che un'operazione del genere richieda molto tempo, ma ci sono alcuni modi in cui potresti accelerare l'operazione:
-
Rimuovi tutti gli indici e i vincoli su
tx_input1
prima di iniziare. La tua query è uno degli esempi in cui un indice non aiuta affatto, ma in realtà fa male performance, perché gli indici devono essere aggiornati insieme alla tabella. Ricrea gli indici e i vincoli dopo aver terminato conUPDATE
. A seconda del numero di indici sul tavolo, puoi aspettarti un aumento delle prestazioni da decente a enorme. -
Aumenta il
work_mem
parametro per questa operazione con ilSET
comanda più in alto che puoi. Più memoria può utilizzare l'operazione di hash, più veloce sarà. Con una tabella così grande probabilmente finirai per avere ancora file temporanei, ma puoi comunque aspettarti un discreto aumento delle prestazioni. -
Aumenta
checkpoint_segments
(omax_wal_size
dalla versione 9.6 in poi) ad un valore alto in modo che ci siano meno checkpoint durante ilUPDATE
operazione. -
Assicurati che le statistiche della tabella su entrambe le tabelle siano accurate, in modo che PostgreSQL possa fornire una buona stima del numero di hash bucket da creare.
Dopo il UPDATE
, se interessa un numero elevato di righe, potresti considerare di eseguire VACUUM (FULL)
su tx_input1
per sbarazzarsi del risultante rigonfiamento del tavolo. Questo bloccherà il tavolo per un tempo più lungo, quindi fallo durante una finestra di manutenzione. Ridurrà le dimensioni della tabella e di conseguenza accelererà le scansioni sequenziali.