2017-10-06 7 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

あなたはBETWEEN状態であることBIGINTし、使用するIPアドレスを変換するためのPythonのUDFを作成することができます。

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のデータはあまり変わらないので、これらの結合で物理的なテーブルを作成することができますので、上記のクエリで毎回結合する必要はありません。

関連する問題