0

私は現在、他の誰かのためにスクリプトを変換しています。彼らの古いコードには、すべての IP と国をリストした CSV ファイルがありました。ファイルの形式は次のとおりです。

16777216    17367039    AU  AUS AUSTRALIA
17367040    17432575    MY  MYS MALAYSIA
17432576    17498111    AU  AUS AUSTRALIA
17498112    17563647    KR  KOR REPUBLIC OF KOREA
17563648    17825791    CN  CHN CHINA

いいです、それが彼らがしたことです、私はそれを新しいMySQL DBにインポートしました。しかし問題は、ここに 111K のレコードがあることです!

比較を行い、国の IP を見つけるには、約 40 秒かかります。現在、すべてのレコードを選択し、次のフィールドより少ないフィールドと多いフィールドと比較します。

$datafile = file("iplist.csv");
    $countries = array();
    foreach($datafile as $data) {
        $data = explode(",", $data);
        foreach($iplist as $ipan => $ip) {
            if($ip > $data[0] && $ip < $data[1]) {
                $countries[$ip] = array($data[2], $data[4]);
            }
        }
    }

もちろん、これがこれを行うための恐ろしい方法であることはわかっています。MySQL でそれを行うと、さらに悪いことになります。つまり、111K のレコードがただそこにあるということです。

私は一日中頭を悩ませてきましたが、とにかくこれを行うより良い方法は考えられません. IP は標準形式で DB に格納されます。私は、MySQL から select を実行し、where ステートメントで more than と less than を実行するだけだと思っていました。しかし、私の人生のために、私はその方法を考えることができます。これを考慮すると、彼らは IP リストを作成する方法です。

foreach($log as $row) {
        $iplist[$row[2]] = $row[2];

        if($last != "") {
            $dif = $last-$row[5];
            $avgtime += $dif;
        }
        $last = $row[5];
    }

レコードごとに 1 つの呼び出しを行うことを考えましたが、各統計ページに通常 120 のレコードが表示される場合、それは mysql 最小値への 120 の呼び出しになるため、アウトです。

この比較を取得するためのより良い効率的な方法を誰か教えてもらえますか?

外部サービスを利用しようと思っていたのですが、リクエストが多すぎてサイトがブラックリストに載ってしまいそうです。

4

2 に答える 2

0

mysqlクエリではjoinを使用する必要があります。

SELECT s.*, g.country_code, g.country_name FROM stats s LEFT JOIN geoip g ON ( g.ip_min <= s.ip AND g.ip_max >= s.ip ) 

次に、1つのクエリでそれを取得します。

INNER JOIN代わりに高速を使用しLEFT JOINますが、IPが範囲外のレコードを選択しません

とにかく、統計テーブルに挿入する前にその場所を見つけて、統計レコードで国のIDを割り当てる方がはるかに良いと思います-あなたもそれに参加する必要がありますが、それははるかに速く動作します

于 2012-10-03T23:03:28.213 に答える
0

これを試してみませんか:

SELECT * FROM table WHERE ip_min >= $your_value and ip_max <= $your_value

ip_minデータの最初の列はどこip_maxで、2 番目の列です。 $your_value明らかに、あなたが知っている ip 値になります。

また、geoIP ロケーションに関しては、MaxMind などの標準データベースの 1 つを参照してください。mod_geoip個人的には、MaxMind データベースを備えたモジュールを使用して、Web サーバー上で国 IP の geoLocation を処理するのが好きです。その後、このデータベースを月単位で更新するだけでよく、アプリケーションで最新の IP データベースを保持しようとする心配はありません。 国コードまたは国名 (または都市まで) を取得するために読み取ることができるスーパーグローバルmod_geoipにいくつかの追加の値を公開するだけです。$_SERVER

于 2012-10-03T22:38:02.010 に答える