我建立了一个每天收集信息的数据库。与日历一样,数据库存储成员的每日金额。如果month与任何现有月份(M-Y)不匹配,则数据库将创建新的html月份表。我已经解决了这个问题,如下:
mysql_query("something goes here");
while(condition)
{
mysql_query("something goes here")
while(condition)
{
mysql_query("something goes here");
while()
{
....................
}
........................
}
}
当我发现它时,该算法运行良好。但是,几天后,它在我的服务器上施加了沉重的负担。然后我在PHP中尝试了相同的算法(但我不能这样)。如何让这个运行得更快? 代码如下:
$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'];
}
答案 0 :(得分:2)
除其他外:
您正在为第一个查询中的每一行运行查询SELECT * FROM member
。此查询独立于循环,因此每次再次运行都是浪费。
对于SELECT * FROM member
查询的每个结果,您正在运行另一个查询(SELECT SUM(amount) AS total FROM account ...
)。此查询存在几个问题:
首先,可以使用GROUP BY
将此查询合并到上一个查询中,以避免必须为每个成员运行一个查询。类似的东西:
SELECT member_id, SUM(amount) AS total FROM account WHERE ... GROUP BY member_id
其次,您正在使用MONTH(dates) = $months AND YEAR(dates) = $years
。这是低效的,因为它迫使服务器检查每一行;如果dates
上有适当的索引,则将其转换为dates BETWEEN '$year-$months-01' AND '$year-$months-31'
上的范围(例如dates
)会加快速度。
一般情况下:避免循环查询。在可能的程度上,生成页面所涉及的查询数量应始终是一个小的,几乎恒定的数字。它不应随着您的数据而增长。
答案 1 :(得分:0)
您是否在MySQL数据库中设置了适当的索引?这可能会导致巨大的性能差异。 http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html