Como você está unindo duas tabelas grandes e não há condições que possam filtrar as linhas, a única estratégia de junção eficiente será uma junção de hash, e nenhum índice pode ajudar com isso.
Primeiro haverá uma varredura sequencial de uma das tabelas, a partir da qual uma estrutura de hash é construída, depois haverá uma varredura sequencial sobre a outra tabela, e o hash será testado para cada linha encontrada. Como qualquer índice poderia ajudar com isso?
Você pode esperar que essa operação demore muito, mas existem algumas maneiras de acelerar a operação:
-
Remova todos os índices e restrições emtx_input1
antes de você começar. Sua consulta é um dos exemplos em que um índice não ajuda em nada, mas na verdade prejudica desempenho, pois os índices devem ser atualizados junto com a tabela. Recrie os índices e restrições depois de terminar com oUPDATE
. Dependendo do número de índices na tabela, você pode esperar um ganho de desempenho decente a enorme.
-
Aumente owork_mem
parâmetro para esta operação com oSET
comando o mais alto que puder. Quanto mais memória a operação de hash puder usar, mais rápida ela será. Com uma tabela tão grande, você provavelmente ainda terá arquivos temporários, mas ainda pode esperar um ganho de desempenho decente.
-
Aumentecheckpoint_segments
(oumax_wal_size
da versão 9.6 em diante) para um valor alto para que haja menos pontos de verificação durante oUPDATE
Operação.
-
Certifique-se de que as estatísticas de ambas as tabelas sejam precisas, para que o PostgreSQL possa fazer uma boa estimativa do número de baldes de hash a serem criados.
Após a
UPDATE
, se afetar um grande número de linhas, considere executar VACUUM (FULL)
em tx_input1
para se livrar do inchaço da tabela resultante. Isso bloqueará a tabela por mais tempo, portanto, faça isso durante uma janela de manutenção. Isso reduzirá o tamanho da tabela e, como consequência, acelerará as varreduras sequenciais.