2016-10-13 7 views
0

私のウェブサイトからのリクエストを拒否するIP範囲は約100,000件のデータベースがあります。効率的なIP範囲の検索PHPとMySQL

これらの範囲を格納するテーブルの形式で、私は、その後ユーザIPかどうかを決定するために、以下のSQLクエリを使用ip2long

を使用して整数値にユーザーにIP変換PHPを使用

ip_from (int) 
ip_to (int) 

ありますテーブルの範囲内に存在する。

SELECT `ip_from` 
FROM `ip2location_proxy` 
WHERE '".$ip."' BETWEEN ip_from AND ip_to LIMIT 1 

これは、サーバーの負荷が大きくなるという問題です。 BETWEENコマンドを使用する代わりのように、IPがデータベースに指定された範囲内にあるかどうかを検出するためのより良い方法を提案できるかどうか疑問に思っています。

+0

聖なる煙は、なぜあなたが禁止している100kのIPアドレスを持っていますか? 1つのHTTPリクエストごとに100kレコードを効率的に検索する方法が本当にあるかどうかはわかりません。 –

+7

インデックスが 'ip_from'または' ip_to'のいずれかにあることを確認してください。 – Barmar

+0

クエリで示唆されているようにip2locationを使用している場合は、はるかに効率的で高速なBIN形式を使用してください。 –

答えて

1

あなたのインデックスが優れていると仮定すると、あなたはそれほど低電力または低速なディスクアクセスシステム上で実行されているが、私は以下の提案:あなたは大規模なホワイトリストの範囲を持っていることが判明した場合

など0 - 2147483648 IPがホワイトリストの範囲にないことを確認してからDBに問い合わせることができます。

<?php 
if($ip > 2147483648) 
{ 
    // consult the ip2location_proxy table 
} 

また、https://www.ip2location.com/databases/px2-ip-country上の例のデータを見て、多分あなたは私たちの間で同様の問題を持っていたip_fromip_to

+0

残念ながら、インデックスは基本的に0から始まります。しかしこれは良い提案でした。 –

1

でない不要な列を削除してくださいすることができます。 UNIONで2つの異なるクエリを使用してみてください。正直なところ、BETWEENが遅いのに対し、なぜこれが速かったのか分かりません。

SELECT `ip_from` 
FROM `ip2location_proxy` 
WHERE '".$ip."' >= ip_from 

UNION ALL 

SELECT `ip_from` 
FROM `ip2location_proxy` 
WHERE '".$ip."' <= ip_to 
関連する問題