Vzhledem k tomu, že spojujete dvě velké tabulky a neexistují žádné podmínky, které by mohly odfiltrovat řádky, jedinou účinnou strategií spojení bude spojení hash as tím žádný index nepomůže.
Nejprve dojde k sekvenčnímu skenování jedné z tabulek, ze které se vytvoří hashovací struktura, pak dojde k sekvenčnímu skenování nad druhou tabulkou a pro každý nalezený řádek se bude zkoumat hash. Jak by s tím mohl pomoci jakýkoli index?
Můžete očekávat, že taková operace bude trvat dlouho, ale existuje několik způsobů, jak operaci urychlit:
-
Odstraňte všechny indexy a omezení na
tx_input1
než začnete. Váš dotaz je jedním z příkladů, kdy index vůbec nepomáhá, ale ve skutečnosti bolí výkonu, protože indexy se musí aktualizovat spolu s tabulkou. Po dokončení pomocíUPDATE
znovu vytvořte indexy a omezení . V závislosti na počtu indexů v tabulce můžete očekávat slušný až masivní nárůst výkonu. -
Zvyšte
work_mem
parametr pro tuto jednu operaci sSET
příkaz tak vysoko, jak jen můžete. Čím více paměti může hašovací operace použít, tím bude rychlejší. S tak velkým stolem budete pravděpodobně stále mít dočasné soubory, ale stále můžete očekávat slušný nárůst výkonu. -
Zvyšte počet
checkpoint_segments
(nebomax_wal_size
od verze 9.6) na vysokou hodnotu, takže běhemUPDATE
bude méně kontrolních bodů operace. -
Ujistěte se, že statistiky tabulek v obou tabulkách jsou přesné, aby PostgreSQL mohl přijít s dobrým odhadem počtu hashových segmentů k vytvoření.
Po UPDATE
, pokud to ovlivňuje velký počet řádků, můžete zvážit spuštění VACUUM (FULL)
na tx_input1
abyste se zbavili výsledného nadýmání stolu. Tím se stůl uzamkne na delší dobu, takže to proveďte během období údržby. Zmenší velikost tabulky a v důsledku toho urychlí sekvenční skenování.