2017-10-06 48 views
0

我有一个帐户和IP地址的列表,我想获取位置摘要。然而,计算对于我们的服务器来说太重了,我想知道是否有办法改变我的代码,我可以得到我所有的结果。账户数据集约为150k行和2列。转换IP地址到位置,需要优化

select city, state, count(*) from(
    select account_id, 256*256*256*one+256*256*two+256*three+four as Converted, city, state from 
     (select *, convert(bigint, split_part(ip_address, '.', 1)) as one, convert(int, split_part(ip_address, '.', 2)) as two, 
     convert(int, split_part(ip_address, '.', 3)) as three, convert(int, split_part(ip_address, '.', 4)) as four from AccountsIP) 
    inner join 
    (select city, state, ip_from, ip_to from ip_ranges a left join ip_locations b on a.ip_location_id = b.ip_location_id 
     where country = 'US') b 
     on (256*256*256*one+256*256*two+256*three+four) between ip_from and ip_to 
) 
group by city, state 

回答

0

您可以创建一个Python UDF转换的IP地址为bigint和使用,在BETWEEN条件:

create or replace function ip_to_ipnum (ip varchar) 
    returns bigint 
    stable as $$ 
    ip_array = ip.split('.') 
    return int(ip_array[0])*16777216+int(ip_array[1])*65536+int(ip_array[2])*256+int(ip_array[3]) 
$$ language plpythonu; 

而且,瓶颈可能是在必须进行排序您ip_rangesip_locations表适当。如果您的数据仅在美国,您可以删除所有其他数据而不是过滤,并按(ip_from, ip_to)对表格进行排序,以便查找效率更高。

而且,由于在ip_rangesip_locations数据没有太大的波动,你可以创建一个连接它们的物理表,这样你就不必每次都加入他们在上面的查询。