I have two tables in Redshift that I am trying to do a join on to get zip code demographics based on a users normalized ip address. By normalized address, I mean that it is concerted to a uniform length string that has the periods stripped out and can be directly compared to one another. For example, this is applied to all ips before any joins are done and is stored in the tables:
lpad(split_part(ip, '.', 1), 3, '0') ||
lpad(split_part(ip, '.', 2), 3, '0') ||
lpad(split_part(ip, '.', 3), 3, '0') ||
lpad(split_part(ip, '.', 4), 3, '0')
so 209.170.151.71
would be transformed into 209170151071
.
I have two tables. This first is visitor_details which contains the following:
-----------------------------
| visitor_id | ip |
-----------------------------
| 1 | 209170151071 |
| 2 | 123170167071 |
... ...
| 50000000 | 001213020341 |
-----------------------------
The I have a table called geo_ip which has the following structure:
----------------------------------------
| start_ip | end_ip | zip |
----------------------------------------
|209170151071 | 209170151071 | 11101 |
|309170151071 | 409170151071 | 11102 |
... ... ...
|509170151071 | 609170151071 | 11103 |
----------------------------------------
I'm trying to run the following query:
WITH vd AS (
SELECT visitor_id,
ip_address as c_ip
FROM dev.visitor_details
)
SELECT
visitor_id,
c_ip,
g.*
FROM
vd
JOIN
dev.geo_ip g
ON vd.c_ip BETWEEN g.startip and g.endip
LIMIT 500;
The sort keys on geo ip are an interleaved sort key using both startip and endip. The table also doesn't seem to be skewed. However, running the query results in a very long execution time (never completed). Looking at the explain I see the following:
XN Limit (cost=0.00..245.17 rows=500 width=238)
-> XN Nested Loop DS_BCAST_INNER (cost=0.00..18442148764959.20 rows=37610983146614 width=238)
Join Filter: ((("inner".startip)::text <= ("outer".ip_address)::text) AND (("inner".endip)::text >= ("outer".ip_address)::text))
-> XN Seq Scan on visitor_details (cost=0.00..596971.20 rows=59697120 width=72)
-> XN Seq Scan on geo_ip g (cost=0.00..56702.71 rows=5670271 width=166)
----- Nested Loop Join in the query plan - review the join predicates to avoid Cartesian products -----
Can anyone make any suggestions on how to either optimize the query of the table setup to make it run efficiently?