Reputation: 338
i have a web app built on code igniter framework on the top of nginx , fastcgi and mysql
i have a payout table . table structure is here.
in this table , country names , perminutecost vs are stored and nearly 56,373 records on it.
in main page , there is a form that requests user to type his cellphone number to retrieve perminute cost.Btw i am using auto-complete feature as user types in
here is my backend code:
$str holds user input(cellphone number)
$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];
this code lets me get perminutecost from a cellphone number.(the table holds just prefixes not all the cell phone numbers)
i did some modifications on nginx and fastcgi to extend timeout limits
but when too much people use the service at the same time , mysqld cpu usage is getting over 100% ,
how could i improve this algorithm ?
thanks.
Upvotes: 1
Views: 489
Reputation: 53870
Convert the Prefix
column from TEXT
to a VARCHAR
column with the minimum required length, and add an index on the Prefix
column.
Then, instead of using a regular expression, use LIKE
with the %
wildcard:
SELECT Destination, PerMinuteCost
FROM `payout` WHERE `Prefix` LIKE '$sub%'
LIMIT 0 , 30
Upvotes: 1
Reputation: 584
You could create another table that stores prefixes for your prefixes. For example, if an entry in your payout table has prefix = 12345, your prefixTable will have 5 associated rows: 1, 12, 123, 1234, and 12345. Each entry will be linked to the original record by a foreign key. To search, you would find an exact match in prefixTable and then join back to your payout table to get the payout information.
This will of course use up more space on the server but should offer you a significant speed boost.
Upvotes: 3
Reputation: 4605
I think just a LIKE '$sub%' would be faster than regex and it might be better for your db if they are not autocompleting until 3 numbers.
Post some example SQL output if you put "EXPLAIN" at the beginning of the sql outside of this script.
Upvotes: 3