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.