vexusdev Posted February 11, 2010 Share Posted February 11, 2010 Hey guys.. I am querying individual phone numbers against a 800k mysql database. Heres how my script works: 1. Upload text file full of numbers 2. grabs 20 phone numbers at a time and put the 20 numbers into an array 3. For loop processes the array in the WHILE loop of the file 4. Query in the process loop: -> Query AreaCode, Exchange(3 next numbers), and first digit of the last 4 numbers -> if no result query only AreaCode and Exchange For each number it literally takes 1 second.. so as you could imagine this is way too slow! Heres my code: $process = 20; $fh = fopen($file,'rb'); $dat = array(); while(!feof($fh)) { //READ INTO ARRAY for ($i = 1; $i <= $process; $i++) { $dat[$i] = fgets($fh); }//$i //PROCESS ARRAY for ($x = 1; $x <= $process; $x++) { $phone = $dat[$x]; if($phone == ''){continue;} $phone = str_replace("(", "", $phone); $phone = str_replace(")", "", $phone); $phone = str_replace("-", "", $phone); $phone = str_replace("-", "", $phone); if(strlen($phone) >= 10) { $phone = substr($phone,0,10); $area = substr($phone,0,3); $exchange = substr($phone,3,3); $firstdigit = substr($phone,6,1); //First Query db Search Area code and prefix and first digit $result = mysql_query("SELECT * FROM provider WHERE areacode='".$area."' AND exchange='".$exchange."' AND firstdigit='".$firstdigit."' AND type='WIRELESS'"); //echo "SELECT * FROM provider WHERE areacode='".$area."' AND exchange='".$exchange."' AND firstdigit='".$firstdigit."' AND (type='WIRELESS' OR type='PCS') LIMIT 1"; if(mysql_num_rows($result)==0) {//no firstdigit so lets try just first 2 $result = mysql_query("SELECT * FROM provider WHERE areacode='".$area."' AND exchange='".$exchange."' AND (type='WIRELESS' OR type='PCS') LIMIT 1"); if(mysql_num_rows($result)==0){ $noncell++; } else { while($row = mysql_fetch_array($result)) { if(strlen($row['email']) >= 3) { $cell++; fwrite($txt, $phone.'@'.$row['email']."\n"); } }//WHILE }//if(mysql) } else {//if result <> 0 while($row = mysql_fetch_array($result)) { if(strlen($row['email']) >= 3) { $cell++; fwrite($txt, $phone.'@'.$row['email']."\n"); } } }//else } else { //Length not 10 $noncell++; } }//$x PROCESS LOOP }//WHILE Quote Link to comment https://forums.phpfreaks.com/topic/191813-mysql-query-against-800k-records-too-slow/ Share on other sites More sharing options...
Mchl Posted February 11, 2010 Share Posted February 11, 2010 What indexes you have defined on this table? Quote Link to comment https://forums.phpfreaks.com/topic/191813-mysql-query-against-800k-records-too-slow/#findComment-1010987 Share on other sites More sharing options...
sader Posted February 11, 2010 Share Posted February 11, 2010 And add LIMIT 1 in this query if this is possible $result = mysql_query("SELECT * FROM provider WHERE areacode='".$area."' AND exchange='".$exchange."' AND firstdigit='".$firstdigit."' AND type='WIRELESS'"); Quote Link to comment https://forums.phpfreaks.com/topic/191813-mysql-query-against-800k-records-too-slow/#findComment-1010991 Share on other sites More sharing options...
vexusdev Posted February 11, 2010 Author Share Posted February 11, 2010 What indexes you have defined on this table? I don't... this database was hell getting it imported from a CSV file.. What do you suggest I do? @sader yeh Ill add that! thanks Quote Link to comment https://forums.phpfreaks.com/topic/191813-mysql-query-against-800k-records-too-slow/#findComment-1010995 Share on other sites More sharing options...
Mchl Posted February 11, 2010 Share Posted February 11, 2010 ALTER TABLE provider ADD INDEX areacode_exchange_firstdigit_type (areacode,exchange,firstdigit,type) Quote Link to comment https://forums.phpfreaks.com/topic/191813-mysql-query-against-800k-records-too-slow/#findComment-1010999 Share on other sites More sharing options...
vexusdev Posted February 11, 2010 Author Share Posted February 11, 2010 ALTER TABLE provider ADD INDEX areacode_exchange_firstdigit_type (areacode,exchange,firstdigit,type) After I run this in phpmyadmin do I have to alter my php code in anyway? Whats this mean? #1170 - BLOB/TEXT column 'areacode' used in key specification without a key length Quote Link to comment https://forums.phpfreaks.com/topic/191813-mysql-query-against-800k-records-too-slow/#findComment-1011001 Share on other sites More sharing options...
Mchl Posted February 11, 2010 Share Posted February 11, 2010 Nope. This will add an index that can possibly speed up your searches. Quote Link to comment https://forums.phpfreaks.com/topic/191813-mysql-query-against-800k-records-too-slow/#findComment-1011003 Share on other sites More sharing options...
Mchl Posted February 11, 2010 Share Posted February 11, 2010 Whats this mean? #1170 - BLOB/TEXT column 'areacode' used in key specification without a key length Oh boy... show me your table structure first... Quote Link to comment https://forums.phpfreaks.com/topic/191813-mysql-query-against-800k-records-too-slow/#findComment-1011005 Share on other sites More sharing options...
vexusdev Posted February 11, 2010 Author Share Posted February 11, 2010 Whats this mean? #1170 - BLOB/TEXT column 'areacode' used in key specification without a key length Oh boy... show me your table structure first... ALTER TABLE provider ADD INDEX areacode_exchange_firstdigit_type (areacode,exchange,firstdigit,type) I changed to (this worked but missing type) ALTER TABLE provider ADD INDEX areacode_exchange_firstdigit (areacode,exchange,firstdigit) Because I made the 3 first tiny ints with correct sizes.. but the type still says the key length problem because its a text field heres my structure: areacode tinyint(3) exchange tinyint(3) firstdigit tinyint(4) type TEXT EDIT: fixed type problem by making it VARCHAR Quote Link to comment https://forums.phpfreaks.com/topic/191813-mysql-query-against-800k-records-too-slow/#findComment-1011014 Share on other sites More sharing options...
Mchl Posted February 11, 2010 Share Posted February 11, 2010 Be aware that tinyint will hold numbers from 0 to 255 only. Instead of TEXT for 'type' you should use either VARCHAR(x) where x is the length of longest value in this column, or ENUM('WIRELESS','PCS','anyOtherTypes') Quote Link to comment https://forums.phpfreaks.com/topic/191813-mysql-query-against-800k-records-too-slow/#findComment-1011019 Share on other sites More sharing options...
vexusdev Posted February 11, 2010 Author Share Posted February 11, 2010 Be aware that tinyint will hold numbers from 0 to 255 only. Instead of TEXT for 'type' you should use either VARCHAR(x) where x is the length of longest value in this column, or ENUM('WIRELESS','PCS','anyOtherTypes') Thanks I did do that, weird thing is when I use your code.. it actually makes the queries slower? Do I have any other solutions maybe code wise? I'm really stumped on how I can speed this up its really way too slow for a practical solution. Quote Link to comment https://forums.phpfreaks.com/topic/191813-mysql-query-against-800k-records-too-slow/#findComment-1011020 Share on other sites More sharing options...
Mchl Posted February 11, 2010 Share Posted February 11, 2010 Could you run something like this and post results EXPLAIN SELECT * FROM provider WHERE areacode = putSomethingHere AND exchange= putSomethingHere AND firstdigit= putSomethingHere AND type='WIRELESS' Quote Link to comment https://forums.phpfreaks.com/topic/191813-mysql-query-against-800k-records-too-slow/#findComment-1011024 Share on other sites More sharing options...
vexusdev Posted February 11, 2010 Author Share Posted February 11, 2010 Could you run something like this and post results EXPLAIN SELECT * FROM provider WHERE areacode = putSomethingHere AND exchange= putSomethingHere AND firstdigit= putSomethingHere AND type='WIRELESS' 1 SIMPLE provider ref areacode_exchange_firstdigit_type areacode_exchange_firstdigit_type 32 const,const,const,const 10 Using where I Noticed if i execute the code in phpmyadmin with your code set it is .1 faster without key its .2 so is there a way to maybe have both of my sql queries combined forexample: where areacode=631 AND exchange=374 AND (firstdigit='5' OR firstdigit='') AND (type='WIRELESS' OR type='PCS') Quote Link to comment https://forums.phpfreaks.com/topic/191813-mysql-query-against-800k-records-too-slow/#findComment-1011025 Share on other sites More sharing options...
vexusdev Posted February 11, 2010 Author Share Posted February 11, 2010 Fixed it.. its fast as hell now! 2k processed in 1 second. THANKS SO MUCH GUYS! SELECT * FROM provider WHERE areacode='".$area."' AND exchange='".$exchange."' AND (firstdigit='".$firstdigit."' OR firstdigit=' ') AND (type='WIRELESS' OR type='PCS') LIMIT 1 thats the new query.. also i used your key alter Quote Link to comment https://forums.phpfreaks.com/topic/191813-mysql-query-against-800k-records-too-slow/#findComment-1011032 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.