Ponieważ łączysz się z dwoma dużymi tabelami i nie ma warunków, które mogłyby odfiltrować wiersze, jedyną skuteczną strategią łączenia będzie łączenie haszujące, a żaden indeks nie może w tym pomóc.
Najpierw nastąpi sekwencyjne skanowanie jednej z tabel, na podstawie której zbudowana jest struktura haszowania, następnie będzie sekwencyjne skanowanie drugiej tabeli, a hash zostanie zbadany dla każdego znalezionego wiersza. Jak jakikolwiek indeks mógłby w tym pomóc?
Możesz spodziewać się, że taka operacja zajmie dużo czasu, ale istnieje kilka sposobów na przyspieszenie operacji:
-
Usuń wszystkie indeksy i ograniczenia na
tx_input1
zanim zaczniesz. Twoje zapytanie jest jednym z przykładów, w których indeks wcale nie pomaga, ale w rzeczywistości boli wydajność, ponieważ indeksy muszą być aktualizowane wraz z tabelą. Odtwórz indeksy i ograniczenia po zakończeniuUPDATE
. W zależności od liczby indeksów na stole, możesz spodziewać się przyzwoitego lub ogromnego przyrostu wydajności. -
Zwiększ
work_mem
parametr dla tej jednej operacji zSET
dowodzić tak wysoko, jak tylko możesz. Im więcej pamięci może wykorzystać operacja skrótu, tym szybciej będzie. Przy tak dużym stole prawdopodobnie nadal będziesz mieć pliki tymczasowe, ale nadal możesz oczekiwać przyzwoitego wzrostu wydajności. -
Zwiększ
checkpoint_segments
(lubmax_wal_size
od wersji 9.6) do wysokiej wartości, aby podczasUPDATE
było mniej punktów kontrolnych operacja. -
Upewnij się, że statystyki obu tabel są dokładne, aby PostgreSQL mógł dobrze oszacować liczbę wiader mieszających do utworzenia.
Po UPDATE
, jeśli ma wpływ na dużą liczbę wierszy, możesz rozważyć uruchomienie VACUUM (FULL)
na tx_input1
pozbyć się powstałego wzdęcia stołu. Spowoduje to zablokowanie tabeli na dłuższy czas, więc zrób to podczas okna konserwacji. Zmniejszy to rozmiar tabeli i w konsekwencji przyspieszy sekwencyjne skanowanie.