I made a database which collects information on a daily basis. as like calender the database stores members’ daily amount. If month doesn’t match any existing month(M-Y) the database will create a new html month table. I have solved this problem, as follows:
mysql_query("something goes here");
while(condition)
{
mysql_query("something goes here")
while(condition)
{
mysql_query("something goes here");
while()
{
....................
}
........................
}
}
This algorithm worked well when I discovered it. However, after a few days, it was placing a heavy load on my server. I then tried the same algorithm in PHP (but I can’t this). How can I make this run faster?
The code is as follows:
$q2=mysql_query("SELECT a.member_id,a.dates,MONTH(dates) AS months,
YEAR(dates)AS years,sum(amount) as sums
FROM account AS a
left join member as m
on(a.member_id=m.member_id)
GROUP BY (SELECT EXTRACT(YEAR_MONTH FROM dates))
ORDER by dates DESC
");
$k=0;
while($data2=mysql_fetch_assoc($q2))
{
$months=$data2['months'];
$years=$data2['years'];
$daten = new DateTime($data2['dates']);
print "<tr><th align='left'><b>".$daten->format('F-Y')."</b></th>";
$q3=mysql_query("select * from member");
while($data3=mysql_fetch_assoc($q3))
{
$id3=$data3['member_id'];
$q4=mysql_query("
SELECT SUM(amount) AS total FROM account
WHERE member_id=$id3
AND month(dates)=$months
AND year(dates)=$years
");
while($data4=mysql_fetch_assoc($q4))
{
$total=$data4['total'];
print "<td class='total'>".number_format($total)."</td>";
}
}
print "<td class='total'><b>".$data2['sums']."</b></td></tr>";
$k=$k+$data2['sums'];
}
Among other things:
You’re running the query
SELECT * FROM memberfor every row in the first query. This query is independent of the loop, so running it again every time is wasteful.For each result from the
SELECT * FROM memberquery, you’re running another query (SELECT SUM(amount) AS total FROM account ...). There are several issues with this query:First of all, this query could be combined into the previous query using a
GROUP BY, to avoid having to run one query for every member. Something like:SELECT member_id, SUM(amount) AS total FROM account WHERE ... GROUP BY member_idSecond of all, you’re using
MONTH(dates) = $months AND YEAR(dates) = $years. This is inefficient, as it forces the server to examine every row; converting it to a range ondates(e.g,dates BETWEEN '$year-$months-01' AND '$year-$months-31') would speed things up if there were an appropriate index ondates.In general: Avoid queries in loops. The number of queries involved in generating a page should, to the degree possible, always be a small, nearly constant number. It should not grow with your data.