Som du antydde är det enda sättet att verkligen vet är att jämföra genomförandeplanerna. Det bästa sättet skulle faktiskt vara att använda EXPLAIN ANALYZE
, så att den faktiskt kör frågan och infogar resultaten i utdata med uppskattningarna, så att du kan få en känsla av frågeplaneraren kontra verkligheten.
Men i allmänhet skulle det jag skulle göra i en situation som denna förmodligen vara att skapa en temp-tabell för klientdeluppsättning och sedan JOIN
det till orders
tabell. Du kan valfritt använda WITH
istället för att göra allt i en fråga.
Så, något i stil med:
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;
På detta sätt, tmp_clients
innehåller endast New York-klienter -- ~5K rader -- och det är den tabellen som kommer att kopplas till ordertabellen.
Du kan också, för att optimera ytterligare, skapa ett index på temp-tabellen (på klient-id) och sedan ANALYZE
det innan du gör JOIN
för att säkerställa att JOIN görs enbart på index. Du skulle vilja kontrollera frågeplanerna i varje enskilt fall för att se den relativa skillnaden (eller bara ha detta i åtanke om JOIN
är inte riktigt så snabbt som du skulle vilja).
Svar på kommentar från @poshest:
Det låter som temptabellerna staplas upp, vilket skulle öka minnesfotavtrycket, och för en långvarig anslutning verkar funktionaliteten vara en minnesläcka.
I så fall skulle det dock inte vara en sann läcka som temptabeller är inriktade på en anslutning. De försvinner automatiskt, men inte förrän efter att anslutningen upphört. Du kan dock få dem att försvinna direkt när du är klar med dem. Helt enkelt DROP
tabellen som du skulle göra med alla andra när du är klar med dem, och jag misstänker att du kommer att kunna anropa funktionen ett gäng gånger -- på samma anslutning -- utan samma sorts monotona minnesökning.