PHP:while循环中的mysql_fetch_array()需要太长时间

时间:2009-05-03 23:59:47

标签: php mysql optimization performance

我正在使用PHP / MySQL为客户创建在线日历。

我发起了<table><tr>,之后有一个while循环,每天创建一个新的<td>,直到该月的最大天数。< / p>

<td>之后的行,PHP通过将$i(计数器)的值与该格式化的Unix时间戳的值进行比较,在MySQL数据库中搜索当天发生的任何事件。数据库的一行。为了在匹配时仅增加内部行计数器,我创建了另一个while循环,为结果提取一个新数组。它显着减慢了加载时间。

这是代码,缩短了,所以你不必阅读不必要的东西:

$qry = "SELECT * FROM events WHERE author=\"$author\"";
$result = mysql_query($qry) or die(mysql_error());

$row = mysql_fetch_array($result);

for ($i = 1; $i <= $max_days; $i++) {

    echo "<td class=\"day\">";

    $rowunixdate_number = date("j", $row['unixdate']);

    if ($rowunixdate_number == $i) {
        while ($rowunixdate_number == $i) {
            $rowtitle = $row['title'];
            echo $rowtitle;
            $row = mysql_fetch_array($result);
            $rowunixdate_number = date("j", $row['unixdate']);
        }
    }

    echo "</td>";

    if (newWeek($day_count)) {
        echo "</tr><tr>";
    }
    $day_count++;

}

4 个答案:

答案 0 :(得分:2)

缓慢很可能是因为你正在进行31次查询,而不是在构建HTML表之前进行1次查询,正如Nael El Shawwa指出的那样 - 如果你想要全部对于该月的给定作者即将发生的事件,您应该在单个SQL查询中选择该事件,然后迭代结果集以实际生成该表。 E.g。

$sql = "SELECT * FROM events WHERE author = '$author' ORDER BY xdate ASC";
$rsEvents = mysql_query($sql);
echo("<table><tr>");
while ($Event = mysql_fetch_array($rsEvents)) {
    echo("<td>[event info in $Event goes here]</td>");
}
echo("</tr></table>");

此外,混合SQL查询和HTML生成通常是个坏主意。您的外部数据应该集中在一个地方,输出数据在另一个地方生成。我的例子通过在HTML生成之前立即使用SQL来关闭它,但这仍然比让HTML块在其中间包含SQL查询更好。

答案 1 :(得分:1)

您是否在MySQL工具中运行该查询以查看需要多长时间?

作者列上有索引吗?

您的PHP没有任何问题。我怀疑查询是问题,没有索引是原因。

答案 2 :(得分:1)

除了上面的评论之外,还尝试优化您的SQL查询,因为这是性能问题最常见的来源之一。

假设您有一个包含标题,日期,Blurb,内容字段的新闻文章表,您只需要获取标题并将其显示为html页面上的列表,

执行“ SELECT * FROM TABLE ” 表示您在执行循环时需要db服务器获取所有字段数据(包括您不打算使用的Blurb和Content)。

如果您将其优化为:

SELECT Title,Date FROM TABLE ”将仅获取必要的数据,并且在服务器利用率方面更有效。

我希望这会对你有所帮助。

答案 3 :(得分:0)

“作者”是个身份证吗?还是一个字符串?无论哪种方式,索引都可以帮助你。

查询不慢,它的for循环导致问题。它不完整;错过$ i循环条件和增量。或者这是一个错字?

为什么不按日期订购查询?

SELECT * FROM events WHERE author=? ORDER BY unixdate ASC

并有一个变量来存储您所在的当前日期,以便在表格中按日期对事件进行分组。为所有事件行提供相同颜色的相同日期。

假设日期是一个不考虑事件时间的unix时间戳,那么你可以这样做:

$currentDate = 0;
while(mysql_fetch_array($result)){
    if($currentDate == $row['unixdate']){
         //code to present an event that is on the same day as the previous event
    }else{
        //code to present an even on a date that is past the previous event
        //you are sorting events by date in the query
    } 

    //update currentDate for next iteration
    $currentDate = $row['unixdate'];
}

如果unixdate包含事件时间,那么您需要添加一些逻辑来提取unix日期时间图,不包括小时和分钟。

希望有所帮助