0xfo7d Posted August 1, 2014 Share Posted August 1, 2014 Hello, First, Says the system that I'm a programmer based in PHP. The system is intended to manage children's registration forms, daycare network. At the moment there are 11,470 records in a table called rishum. I want to pull out the statistics form: Take a few minutes to this page costs. Code for retrieving data is: <center> <br /> <table border=0 cellspacing=1 cellpadding=0 width="1000px"> <tr> <td align='right' valign='middle' style='width: 40%;text-align: right;padding: 5px;background: #061B2A;color: #FFF;font-weight: bold;'>שם המוסד</td> <td align='right' valign='middle' style='width: 15%;text-align: right;padding: 5px;background: #061B2A;color: #FFF;font-weight: bold;'>רישום לקייטנה</td> <td align='right' valign='middle' style='width: 15%;text-align: right;padding: 5px;background: #061B2A;color: #FFF;font-weight: bold;'>משלמים לקייטנה</td> <td align='center' valign='middle' style='width: 10%;text-align: center;padding: 5px;background: #061B2A;color: #FFF;font-weight: bold;'>רישום לצהרון</td> <td align='center' valign='middle' style='width: 10%;text-align: center;padding: 5px;background: #061B2A;color: #FFF;font-weight: bold;'>משלמים לצהרון</td> <td align='center' valign='middle' style='width: 5%;text-align: center;padding: 5px;background: #061B2A;color: #FFF;font-weight: bold;'>רשומים לבית ספר</td> <td align='center' valign='middle' style='width: 5%;text-align: center;padding: 5px;background: #061B2A;color: #FFF;font-weight: bold;'>רשומים לגן</td> </tr> </table> <? ?> <?php $res1 = mysql_query("SELECT * FROM `places` ORDER BY `name` desc"); while($row1 = mysql_fetch_array($res1)) { $res_ci = mysql_query("SELECT * FROM (SELECT * FROM `rishum` WHERE `status`!='not_relevant' AND `city`='".$row1["id"]."' AND `rishum_to`='1' AND `aougust_form`='".$_GET["aougust_form"]."' AND `date`>='".$filterByYear."/04/22' AND `date`<='".($filterByYear+1)."/04/21') as c GROUP BY `talmid_id`"); $row_ci = mysql_num_rows($res_ci); $res_ci_PAY = mysql_query("SELECT * FROM (SELECT * FROM `rishum` WHERE `status`='payed' AND `city`='".$row1["id"]."' AND `rishum_to`='1' AND `aougust_form`='".$_GET["aougust_form"]."' AND `date`>='".$filterByYear."/04/22' AND `date`<='".($filterByYear+1)."/04/21') as c GROUP BY `talmid_id`"); $row_ci_PAY = mysql_num_rows($res_ci_PAY); $res2_ci = mysql_query("SELECT * FROM (SELECT * FROM `rishum` WHERE `status`!='not_relevant' AND `city`='".$row1["id"]."' AND `rishum_to`='2' AND `aougust_form`='".$_GET["aougust_form"]."' AND `date`>='".$filterByYear."/04/22' AND `date`<='".($filterByYear+1)."/04/21') as c GROUP BY `talmid_id`"); $row2_ci = mysql_num_rows($res2_ci); $res2_ci_PAY = mysql_query("SELECT * FROM (SELECT * FROM `rishum` WHERE `status`='payed' AND `city`='".$row1["id"]."' AND `rishum_to`='2' AND `aougust_form`='".$_GET["aougust_form"]."' AND `date`>='".$filterByYear."/04/22' AND `date`<='".($filterByYear+1)."/04/21') as c GROUP BY `talmid_id`"); $row2_ci_PAY = mysql_num_rows($res2_ci_PAY); $res_countPerCity_school = mysql_query("SELECT * FROM (SELECT * FROM `rishum` WHERE `status`!='not_relevant' AND `city`='".$row1["id"]."' AND `soog_mosad`='school' AND `aougust_form`='".$_GET["aougust_form"]."' AND `date`>='".$filterByYear."/04/22' AND `date`<='".($filterByYear+1)."/04/21') as c GROUP BY `talmid_id`"); $row_countPerCity_school = mysql_num_rows($res_countPerCity_school); $res_countPerCity_gan = mysql_query("SELECT * FROM (SELECT * FROM `rishum` WHERE `status`!='not_relevant' AND `city`='".$row1["id"]."' AND `soog_mosad`='gan' AND `aougust_form`='".$_GET["aougust_form"]."' AND `date`>='".$filterByYear."/04/22' AND `date`<='".($filterByYear+1)."/04/21') as c GROUP BY `talmid_id`"); $row_countPerCity_gan = mysql_num_rows($res_countPerCity_gan); if(($row_ci+$row2_ci) > 0) { ?> <div class="module" style="width: 1000px"><div class="module_name" align='center' style='cursor: hand;cursor: pointer;'> <table border=0 cellspacing=1 cellpadding=0 width="1000px"> <tr class="try"> <td align="right" style="text-align: right;width: 40%;padding: 5px;color: #FFF;font-weight: bold;"><?=$row1["name"];?></td> <td align="center" style="text-align: center;width: 15%;padding: 5px;color: #FFF;font-weight: bold;"><?=$row_ci;?></td> <td align="center" style="text-align: center;width: 15%;padding: 5px;color: #FFF;font-weight: bold;"><?=$row_ci_PAY;?></td> <td align="center" style="text-align: center;width: 10%;padding: 5px;color: #FFF;font-weight: bold;"><?=$row2_ci;?></td> <td align="center" style="text-align: center;width: 10%;padding: 5px;color: #FFF;font-weight: bold;"><?=$row2_ci_PAY;?></td> <td align="center" style="text-align: center;width: 5%;padding: 5px;color: #FFF;font-weight: bold;"><?=$row_countPerCity_school;?></td> <td align="center" style="text-align: center;width: 5%;padding: 5px;color: #FFF;font-weight: bold;"><?=$row_countPerCity_gan;?></td> </tr> </table> </div><div class="module_links2" align='center'> <table border=0 cellspacing=1 cellpadding=0 width="1000px"> <? $resCITY = mysql_query("SELECT * FROM `schools` WHERE `city`='".$row1["id"]."' ORDER BY `type` desc,`name`"); while($rowCITY = mysql_fetch_array($resCITY)) { $res = mysql_query("SELECT * FROM (SELECT * FROM `rishum` WHERE `status`!='not_relevant' AND `the_mosad`='".$rowCITY["id"]."' AND `rishum_to`='1' AND `aougust_form`='".$_GET["aougust_form"]."' AND `date`>='".$filterByYear."/04/22' AND `date`<='".($filterByYear+1)."/04/21') as c GROUP BY `talmid_id`"); $row = mysql_num_rows($res); $res_PAY = mysql_query("SELECT * FROM (SELECT * FROM `rishum` WHERE `status`='payed' AND `the_mosad`='".$rowCITY["id"]."' AND `rishum_to`='1' AND `aougust_form`='".$_GET["aougust_form"]."' AND `date`>='".$filterByYear."/04/22' AND `date`<='".($filterByYear+1)."/04/21') as c GROUP BY `talmid_id`"); $row_PAY = mysql_num_rows($res_PAY); $res2 = mysql_query("SELECT * FROM (SELECT * FROM `rishum` WHERE `status`!='not_relevant' AND `the_mosad`='".$rowCITY["id"]."' AND `rishum_to`='2' AND `aougust_form`='".$_GET["aougust_form"]."' AND `date`>='".$filterByYear."/04/22' AND `date`<='".($filterByYear+1)."/04/21') as c GROUP BY `talmid_id`"); $row2 = mysql_num_rows($res2); $res2_PAY = mysql_query("SELECT * FROM (SELECT * FROM `rishum` WHERE `status`='payed' AND `the_mosad`='".$rowCITY["id"]."' AND `rishum_to`='2' AND `aougust_form`='".$_GET["aougust_form"]."' AND `date`>='".$filterByYear."/04/22' AND `date`<='".($filterByYear+1)."/04/21') as c GROUP BY `talmid_id`"); $row2_PAY = mysql_num_rows($res2_PAY); if(($row+$row2) > 0) { ?> <tr> <td align="rigth" style="width: 40%;text-align: right;padding: 5px;background: #ddd;color: #444444;font-weight: bold;"><?=$rowCITY["name"];?></td> <td align="center" style="width: 15%;text-align: center;padding: 5px;background: #ddd;color: #444444;font-weight: bold;"><a href="index.php?action=rishum&sa=statistics&year=<?=$filterByYear;?>&city=<?=$row1["id"];?>&school=<?=$rowCITY["id"];?>&tofesType=1&typeee=<?=$rowCITY["type"];?><? if($_GET["aougust_form"]) { echo "&aougust_form=1"; } ?>"><?=$row;?></a></td> <td align="center" style="width: 15%;text-align: center;padding: 5px;background: #ddd;color: #444444;font-weight: bold;"><?=$row_PAY;?></td> <td align="center" style="width:10%;text-align: center;padding: 5px;background: #ddd;color: #444444;font-weight: bold;"><a href="index.php?action=rishum&sa=statistics&year=<?=$filterByYear;?>&city=<?=$row1["id"];?>&school=<?=$rowCITY["id"];?>&tofesType=2&typeee=<?=$rowCITY["type"];?><? if($_GET["aougust_form"]) { echo "&aougust_form=1"; } ?>"><?=$row2;?></a></td> <td align="center" style="width:10%;text-align: center;padding: 5px;background: #ddd;color: #444444;font-weight: bold;"><?=$row2_PAY;?></td> <td align="center" style="width:5%;text-align: center;padding: 5px;background: #ddd;color: #444444;font-weight: bold;"> --- </td> <td align="center" style="width:5%;text-align: center;padding: 5px;background: #ddd;color: #444444;font-weight: bold;"> --- </td> </tr> <? } } ?> </table> </div></div> <? } } $res_all = mysql_query("SELECT * FROM (SELECT * FROM `rishum` WHERE `status`!='not_relevant' AND `rishum_to`='1' AND `aougust_form`='".$_GET["aougust_form"]."' AND `date`>='".$filterByYear."/04/22' AND `date`<='".($filterByYear+1)."/04/21') as c GROUP BY `talmid_id`"); $row_all = mysql_num_rows($res_all); $res_all_PAY = mysql_query("SELECT * FROM (SELECT * FROM `rishum` WHERE `status`='payed' AND `rishum_to`='1' AND `aougust_form`='".$_GET["aougust_form"]."' AND `date`>='".$filterByYear."/04/22' AND `date`<='".($filterByYear+1)."/04/21') as c GROUP BY `talmid_id`"); $row_all_PAY = mysql_num_rows($res_all_PAY); $res_all2 = mysql_query("SELECT * FROM (SELECT * FROM `rishum` WHERE `status`!='not_relevant' AND `rishum_to`='2' AND `aougust_form`='".$_GET["aougust_form"]."' AND `date`>='".$filterByYear."/04/22' AND `date`<='".($filterByYear+1)."/04/21') as c GROUP BY `talmid_id`"); $row_all2 = mysql_num_rows($res_all2); $res_all2_PAY = mysql_query("SELECT * FROM (SELECT * FROM `rishum` WHERE `status`='payed' AND `rishum_to`='2' AND `aougust_form`='".$_GET["aougust_form"]."' AND `date`>='".$filterByYear."/04/22' AND `date`<='".($filterByYear+1)."/04/21') as c GROUP BY `talmid_id`"); $row_all2_PAY = mysql_num_rows($res_all2_PAY); ?> <table border=0 cellspacing=1 cellpadding=0 width="1000px"> <tr> <td align='right' valign='middle' style='width: 40%;text-align: right;padding: 10px;background: #000;color: #FFF;font-weight: bold;'>סה"כ טפסי רישום</td> <td align='center' valign='middle' style='width: 15%;text-align: center;padding: 10px;background: #000;color: #FFF;font-weight: bold;'><?=$row_all;?></td> <td align='center' valign='middle' style='width: 15%;text-align: center;padding: 10px;background: #000;color: #FFF;font-weight: bold;'><?=$row_all_PAY;?></td> <td align='center' valign='middle' style='width: 10%;text-align: center;padding: 10px;background: #000;color: #FFF;font-weight: bold;'><?=$row_all2;?></td> <td align='center' valign='middle' style='width: 10%;text-align: center;padding: 10px;background: #000;color: #FFF;font-weight: bold;'><?=$row_all2_PAY;?></td> <td align='center' valign='middle' style='width: 5%;text-align: center;padding: 10px;background: #000;color: #FFF;font-weight: bold;'> --- </td> <td align='center' valign='middle' style='width: 5%;text-align: center;padding: 10px;background: #000;color: #FFF;font-weight: bold;'> --- </td> </tr> </table> </center> Quote Link to comment https://forums.phpfreaks.com/topic/290219-very-slow-retrieval-of-data-from-a-database-what-can-you-do/ Share on other sites More sharing options...
mogosselin Posted August 1, 2014 Share Posted August 1, 2014 Hello Oxfo7d! Your code is a little bit hard to read because there are no indentation. But, I've seen that you seems to do SQL queries in a loop: $res1 = mysql_query("SELECT * FROM `places` ORDER BY `name` desc"); while($row1 = mysql_fetch_array($res1)) { ... } So all the queries will inside the while will be run for each places. How many 'places' do you have? Because it looks like you have about 15 queries with sub selects (SELECT * FROM (SELECT ...)) which are not the most performant type of queries you could do. I think that's mostly your problem. You should try to do less queries and less queries with sub-select. 11.5k rows isn't big at all, it shouldn't even be a problem. Quote Link to comment https://forums.phpfreaks.com/topic/290219-very-slow-retrieval-of-data-from-a-database-what-can-you-do/#findComment-1486612 Share on other sites More sharing options...
Jacques1 Posted August 1, 2014 Share Posted August 1, 2014 The problem is that the entire code is broken beyond repair. Seriously, what on earth are you doing there? Not only do the queries make absolutely no sense. You've also copied and pasted them around like crazy. And why on earth do you download the entire tables only to count the rows? Never heard of COUNT(*)? I'm not surprised at all that this takes several minutes. You've done everything to make it as slow as possible. Unfortunately, this won't be an easy fix. What can I say? Throw away the script, learn the basics of PHP and SQL and start over. Or find a programmer who's willing to write the code for you. 1 Quote Link to comment https://forums.phpfreaks.com/topic/290219-very-slow-retrieval-of-data-from-a-database-what-can-you-do/#findComment-1486615 Share on other sites More sharing options...
Psycho Posted August 1, 2014 Share Posted August 1, 2014 (edited) OK guys, no need to be so harsh. We were all beginners at one point. 0xfo7d, there are a few specific problems: 1) You are not using JOINs to relate your tables in the queries. Being able to JOIN tables in your queries is the real power that a relational database gives you. It can be hard to grasp at first. Take a little time and look at a tutorial or two. Never, ever run queries in loops unless you have no other alternative. And that should be very few scenarios. 2) You are using '*' in all the queries even though you don't need all the data. 3) You are querying ALL the records only to get the count. I'll look at the queries a little more to see if I can provide some revised ones to get just the data you need with only one or a few queries (with no loops). But, it's difficult without understanding the schema. EDIT: I'll add a #4: SELECT * FROM (SELECT * FROM `rishum` WHERE `status`!='not_relevant' AND `city`='".$row1["id"]."' AND `rishum_to`='1' AND `aougust_form`='".$_GET["aougust_form"]."' AND `date`>='".$filterByYear."/04/22' AND `date`<='".($filterByYear+1)."/04/21') AS c GROUP BY `talmid_id` This really makes no sense. Why would you run a sub-query only so you can select all the records and do a GROUP BY? You can simply do the GROUP BY in the inner query and not need to make it a sub-query: SELECT * FROM `rishum` WHERE `status`!='not_relevant' AND `city`='".$row1["id"]."' AND `rishum_to`='1' AND `aougust_form`='".$_GET["aougust_form"]."' AND `date`>='".$filterByYear."/04/22' AND `date`<='".($filterByYear+1)."/04/21' GROUP BY `talmid_id` Edited August 1, 2014 by Psycho 1 Quote Link to comment https://forums.phpfreaks.com/topic/290219-very-slow-retrieval-of-data-from-a-database-what-can-you-do/#findComment-1486621 Share on other sites More sharing options...
Jacques1 Posted August 1, 2014 Share Posted August 1, 2014 You don't use a GROUP BY clause at all. The sole purpose of grouping is to apply an aggregate function like COUNT() or SUM() to specific subsets of the result set. No aggregate function, no grouping. In fact, a proper database system wouldn't even let you run the query. This violates the SQL standard in every possible way. Unfortunately, MySQL accepts almost anything, so even the worst mistakes tend to go unnoticed. Dropping the raw user input (like $_GET["aougust_form"]) into the queries also isn't the best idea. You think nobody would attack a day care site? I wouldn't bet on that. Quote Link to comment https://forums.phpfreaks.com/topic/290219-very-slow-retrieval-of-data-from-a-database-what-can-you-do/#findComment-1486623 Share on other sites More sharing options...
Psycho Posted August 1, 2014 Share Posted August 1, 2014 You don't use a GROUP BY clause at all. Yes, I know. I was only pointing out that using a sub-query to get the records and using an outer query to do a GROUP BY Quote Link to comment https://forums.phpfreaks.com/topic/290219-very-slow-retrieval-of-data-from-a-database-what-can-you-do/#findComment-1486626 Share on other sites More sharing options...
phpPeter Posted August 1, 2014 Share Posted August 1, 2014 First, please clean up your queries and remove these senseless "group by"s. As long, as it is absolutely unclear, what the query should do at all, it is difficult to help you in detail. I will try to understand this: $res_all = mysql_query("SELECT * FROM (SELECT * FROM `rishum` WHERE `status`!='not_relevant' AND `rishum_to`='1' AND `aougust_form`='".$_GET["aougust_form"]."' AND `date`>='".$filterByYear."/04/22' AND `date`<='".($filterByYear+1)."/04/21') as c GROUP BY `talmid_id`");$row_all = mysql_num_rows($res_all); should mean:--> SELECT count(*) as row_all FROM rishum WHERE status != "not relevant" and rishum_to=1 and aougust_form=? AND date BETWEEN ? AND ? $res_all_PAY = mysql_query("SELECT * FROM (SELECT * FROM `rishum` WHERE `status`='payed' AND `rishum_to`='1' AND `aougust_form`='".$_GET["aougust_form"]."' AND `date`>='".$filterByYear."/04/22' AND `date`<='".($filterByYear+1)."/04/21') as c GROUP BY `talmid_id`");$row_all_PAY = mysql_num_rows($res_all_PAY); --> SELECT count(*) AS row_all_PAY FROM rishum WHERE status = "payed" and rishum_to=1 and aougust_form=? AND date BETWEEN ? AND ? $res_all2 = mysql_query("SELECT * FROM (SELECT * FROM `rishum` WHERE `status`!='not_relevant' AND `rishum_to`='2' AND `aougust_form`='".$_GET["aougust_form"]."' AND `date`>='".$filterByYear."/04/22' AND `date`<='".($filterByYear+1)."/04/21') as c GROUP BY `talmid_id`");$row_all2 = mysql_num_rows($res_all2); --> SELECT count(*) AS row_all2 FROM rishum WHERE status != "not relevant" and rishum_to=2 and aougust_form=? AND date BETWEEN ? AND ? $res_all2_PAY = mysql_query("SELECT * FROM (SELECT * FROM `rishum` WHERE `status`='payed' AND `rishum_to`='2' AND `aougust_form`='".$_GET["aougust_form"]."' AND `date`>='".$filterByYear."/04/22' AND `date`<='".($filterByYear+1)."/04/21') as c GROUP BY `talmid_id`");$row_all2_PAY = mysql_num_rows($res_all2_PAY); --> SELECT count(*) as row_all2_PAY FROM rishum WHERE status = "payed" and rishum_to=2 and aougust_form=? AND date BETWEEN ? AND ? ... So, first, you should rework your queries to my suggestions. This will improve your performance multiple times, because you don't have to transfer all datasets to count them afterwards, but this will do the query engine for you. However, I still haven't found out, what the "talmid_id" should be good for... Then, you can define the right indices. I think, you can leave it away with such a tiny table (the 11k records will be stored in the mem buffer after first query). But to be accurate, lets define the required index. My suggestion: CREATE INDEX i1 ON rishum(rishum_to, aougust_form, date, status); After that, it should be a matter of milliseconds... ;-) Quote Link to comment https://forums.phpfreaks.com/topic/290219-very-slow-retrieval-of-data-from-a-database-what-can-you-do/#findComment-1486630 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.