1

我有一个基于 nginx、fastcgi 和 mysql 之上的代码点火器框架的网络应用程序

我有一个支付表。表结构在这里

在此表中,存储了国家名称、每分钟成本与近 56,373 条记录。


在主页中,有一个表格要求用户输入他的手机号码以检索每分钟费用。顺便说一句,我在用户输入时使用自动完成功能

这是我的后端代码:

$str 保存用户输入(手机号码)

$ret = 真;$计数 = 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];

这段代码让我从手机号码中获取每分钟费用。(该表仅包含前缀而不是所有手机号码)

我对 nginx 和 fastcgi 做了一些修改以延长超时限制

但是当太多人同时使用该服务时,mysqld cpu 使用率超过 100%,

我该如何改进这个算法?

谢谢。

4

3 回答 3

3

我认为只是一个 LIKE '$sub%' 会比正则表达式更快,如果它们直到 3 个数字才自动完成,它可能对你的数据库更好。

如果您在此脚本之外的 sql 开头放置“EXPLAIN”,请发布一些示例 SQL 输出。

于 2012-03-06T15:01:35.743 回答
3

您可以创建另一个表来存储前缀的前缀。例如,如果您的支付表中的条目具有前缀 = 12345,则您的前缀表将有 5 个关联的行:1、12、123、1234 和 12345。每个条目将通过外键链接到原始记录。要进行搜索,您将在 prefixTable 中找到完全匹配的内容,然后返回您的支付表以获取支付信息。

这当然会占用服务器上的更多空间,但应该会显着提高速度。

于 2012-03-06T15:06:52.293 回答
1

Prefix列从转换为所需长度最小TEXT的列,并在该列上添加索引。VARCHARPrefix

然后,不要使用正则表达式,而是使用LIKE通配符%

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