Jak wspomniałeś, jedynym sposobem na naprawdę wiem, jest porównanie planów wykonawczych. W rzeczywistości najlepszym sposobem byłoby użycie EXPLAIN ANALYZE
, dzięki czemu faktycznie wykonuje zapytanie i wstawia wyniki do danych wyjściowych wraz z szacunkami, dzięki czemu można zorientować się, jak planer zapytań różni się od rzeczywistości.
Jednak ogólnie rzecz biorąc, to, co zrobiłbym w takiej sytuacji, to prawdopodobnie utworzenie tabeli tymczasowej dla podzbioru klienta, a następnie JOIN
że do orders
stół. Możesz opcjonalnie użyć WITH
zamiast tego zrobić wszystko w jednym zapytaniu.
A więc coś takiego:
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;
W ten sposób tmp_clients
zawiera tylko klientów z Nowego Jorku -- ~5 tys. wierszy -- i to ta tabela zostanie połączona z tabelą zamówień.
Możesz również, w celu dalszej optymalizacji, utworzyć indeks w tabeli tymczasowej (na identyfikatorze klienta), a następnie ANALYZE
to przed wykonaniem JOIN
aby upewnić się, że JOIN jest wykonywane wyłącznie na indeksie. Chciałbyś sprawdzić plany zapytań w każdym przypadku, aby zobaczyć względną różnicę (lub po prostu o tym pamiętaj, jeśli JOIN
nie jest tak szybki, jak byś chciał).
Odpowiedź na komentarz od @poshest:
To brzmi jak tabele tymczasowe układają się w stos, co zwiększyłoby zużycie pamięci, a w przypadku długotrwałego połączenia funkcjonalność wydaje się być wyciekiem pamięci.
W takim przypadku nie byłby to jednak prawdziwy przeciek, ponieważ tabele tymczasowe są objęte zakresem połączenia. Znikają automatycznie, ale dopiero po zakończeniu połączenia. Możesz jednak sprawić, że znikną natychmiast, gdy z nimi skończysz. Po prostu DROP
tabelę tak jak każdą inną, gdy już z nimi skończysz, i podejrzewam, że będziesz w stanie wywołać funkcję kilka razy - przy tym samym połączeniu - bez tego samego rodzaju monotonicznego wzrostu pamięci. /P>