1

私はnginx、fastcgi、mysqlの上にコードイグナイターフレームワーク上に構築されたWebアプリを持っています

ペイアウトテーブルがあります。テーブル構造はこちらです。

この表には、国名、perminutecost vsが保存され、56,373件近くのレコードが記録されています。


メインページには、ユーザーに携帯電話番号を入力して1分あたりの費用を取得するように求めるフォームがあります。ところで、ユーザーが入力するときにオートコンプリート機能を使用しています。

これが私のバックエンドコードです:

$ strはユーザー入力(携帯電話番号)を保持します

$ ret = true; $ count = 3;

        while($ret){
            $sub = substr($str,0,$count); //9053
            $ret = R::getAll("SELECT Destination,PerMinuteCost FROM `payout` WHERE `Prefix` REGEXP '^$sub(.)*$' LIMIT 0 , 30");
            $count++;
        }

        $sub = substr($str,0,$count-2);

        $ret =  R::getAll("SELECT Destination,PerMinuteCost FROM `payout` WHERE `Prefix` REGEXP '^$sub(.)*$' LIMIT 0 , 30");

        return $ret[0];

このコードを使用すると、携帯電話番号から1分あたりのコストを取得できます(表には、すべての携帯電話番号ではなくプレフィックスのみが含まれています)

タイムアウト制限を拡張するためにnginxとfastcgiにいくつかの変更を加えました

しかし、同時にサービスを使用する人が多すぎると、mysqld cpuの使用率が100%を超えます。

このアルゴリズムをどのように改善できますか?

ありがとう。

4

3 に答える 3

3

プレフィックスのプレフィックスを格納する別のテーブルを作成できます。たとえば、ペイアウトテーブルのエントリのプレフィックスが12345の場合、prefixTableには1、12、123、1234、12345の5つの行が関連付けられます。各エントリは外部キーによって元のレコードにリンクされます。検索するには、prefixTableで完全に一致するものを見つけてから、ペイアウトテーブルに戻ってペイアウト情報を取得します。

もちろん、これによりサーバー上のスペースがさらに消費されますが、速度が大幅に向上するはずです。

于 2012-03-06T15:06:52.293 に答える
3

LIKE '$sub%' は正規表現よりも高速であり、3 つの数字までオートコンプリートされない場合は、DB にとってより良い可能性があると思います。

このスクリプトの外側の SQL の先頭に「EXPLAIN」を配置した場合の SQL 出力の例を投稿してください。

于 2012-03-06T15:01:35.743 に答える
1

列を必要最小限の長さの列に変換し、Prefix列にインデックスを追加します。TEXTVARCHARPrefix

次に、正規表現を使用する代わりにLIKE%ワイルドカードを使用します。

SELECT Destination, PerMinuteCost
FROM `payout` WHERE `Prefix` LIKE '$sub%'
LIMIT 0 , 30
于 2012-03-06T15:30:19.333 に答える