PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

PostgreSQL:melhor maneira de juntar pequenos subconjuntos de grandes tabelas


Como você mencionou, a única maneira de verdadeiramente saber é comparar os planos de execução. Na verdade, a melhor maneira seria usar EXPLAIN ANALYZE , para que ele realmente execute a consulta e insira os resultados na saída com as estimativas, para que você possa ter uma noção do planejador da consulta versus a realidade.

No entanto, em geral, o que eu faria em uma situação como essa provavelmente seria criar uma tabela temporária para o subconjunto do cliente e, em seguida, JOIN isso para os orders tabela. Opcionalmente, você pode usar WITH em vez de fazer tudo em uma consulta.

Então, algo como:
CREATE TEMP TABLE tmp_clients AS
SELECT c.clientid
FROM clients c
WHERE c.city = 'New York'
ORDER BY c.clientid;

SELECT *
FROM orders AS o
JOIN tmp_clients AS c ON (o.clientid = c.clientid)
ORDER BY o.clientid;

Dessa forma, tmp_clients contém apenas os clientes de Nova York -- ~5K linhas -- e é essa tabela que será unida à tabela de pedidos.

Você também pode, para otimizar ainda mais, criar um índice na tabela temporária (no clientid) e, em seguida, ANALYZE antes de fazer o JOIN para garantir que o JOIN seja feito puramente no índice. Você gostaria de verificar os planos de consulta em cada caso para ver a diferença relativa (ou apenas manter isso em mente se o JOIN não é tão rápido quanto você gostaria).

Resposta ao comentário de @poshest:

Isso soa como as tabelas temporárias estão se acumulando, o que aumentaria o consumo de memória e, para uma conexão de longa duração, a funcionalidade parece ser um vazamento de memória.

Nesse caso, não seria um vazamento verdadeiro, pois as tabelas temporárias estão no escopo de uma conexão. Eles desaparecem automaticamente, mas não até que a conexão termine. No entanto, você pode fazê-los desaparecer imediatamente quando terminar com eles. Simplesmente DROP a tabela como você faria com qualquer outra depois de terminar com eles, e eu suspeito que você será capaz de chamar a função um monte de vezes - na mesma conexão - sem o mesmo tipo de aumento monotônico da pegada de memória.