Eftersom du går med i två stora tabeller och det inte finns några villkor som kan filtrera bort rader, kommer den enda effektiva join-strategin att vara en hash-join, och inget index kan hjälpa till med det.
Först kommer det att göras en sekventiell skanning av en av tabellerna, från vilken en hashstruktur byggs, sedan kommer det att göras en sekventiell skanning över den andra tabellen, och hashen kommer att undersökas för varje rad som hittas. Hur skulle något index kunna hjälpa till med det?
Du kan förvänta dig att en sådan operation kommer att ta lång tid, men det finns några sätt som du kan påskynda operationen på:
-
Ta bort alla index och begränsningar på
tx_input1
innan du börjar. Din fråga är ett av exemplen där ett index inte hjälper alls, utan faktiskt gör ont prestanda, eftersom indexen måste uppdateras tillsammans med tabellen. Återskapa indexen och begränsningarna när du är klar medUPDATE
. Beroende på antalet index på bordet kan du förvänta dig en anständig till massiv prestandavinst. -
Öka
work_mem
parameter för denna operation medSET
kommando så högt du kan. Ju mer minne hashoperationen kan använda, desto snabbare blir den. Med ett så stort bord kommer du förmodligen fortfarande att ha tillfälliga filer, men du kan fortfarande förvänta dig en anständig prestandavinst. -
Öka
checkpoint_segments
(ellermax_wal_size
från version 9.6 på) till ett högt värde så att det finns färre kontrollpunkter underUPDATE
operation. -
Se till att tabellstatistiken för båda tabellerna är korrekt, så att PostgreSQL kan komma med en bra uppskattning av antalet hash-buckets som ska skapas.
Efter UPDATE
, om det påverkar ett stort antal rader kan du överväga att köra VACUUM (FULL)
på tx_input1
för att bli av med den resulterande bordsvällningen. Detta kommer att låsa bordet under en längre tid, så gör det under ett underhållsfönster. Det kommer att minska storleken på tabellen och som en konsekvens påskynda sekventiell genomsökning.