简体   繁体   English

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

[英]PHP: mysql_fetch_array() in a while-loop takes too long

I am creating an online calendar for a client using PHP/MySQL. 我正在使用PHP / MySQL为客户端创建在线日历。

I initiated a <table> and <tr> , and after that have a while loop that creates a new <td> for each day, up to the max number of days in the month. 我启动了<table><tr> ,然后有一个while循环,可以为每天创建一个新的<td> ,直到一个月的最大天数。

The line after the <td> , PHP searches a MySQL database for any events that occur on that day by comparing the value of $i (the counter) to the value of the formatted Unix timestamp within that row of the database. PHP在<td>之后的行中,通过将$i (计数器)的值与该数据库行中格式化的Unix时间戳的值进行比较,PHP在MySQL数据库中搜索当天发生的任何事件。 In order to increment the internal row counter ONLY when a match is made, I have made another while loop that fetches a new array for the result. 为了仅在匹配时增加内部行计数器,我进行了另一个while循环,以获取结果的新数组。 It is significantly slowing down loading time. 这极大地减慢了加载时间。

Here's the code, shortened so you don't have to read the unnecessary stuff: 这是缩短的代码,因此您不必阅读不必要的内容:

$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++;

}

The slowness is most likely because you're doing 31 queries, instead of 1 query before you build the HTML table, as Nael El Shawwa pointed out -- if you're trying to get all the upcoming events for a given author for the month, you should select that in a single SQL query, and then iterate over the result set to actually generate the table. 缓慢的原因很可能是因为您正在构建HTML表之前执行31个查询,而不是1个查询,正如Nael El Shawwa指出的那样-如果您要获取该月给定作者的所有即将发生的事件,您应该在单个SQL查询中选择该查询,然后遍历结果集以实际生成该表。 Eg 例如

$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>");

Furthermore, it's usually a bad idea to intermix SQL queries and HTML generation. 此外,将SQL查询和HTML生成混合在一起通常不是一个好主意。 Your external data should be gathered in one place, the output data generated in another. 您的外部数据应收集在一个地方,输出数据应收集在另一个地方。 My example cuts it close, by having the SQL immediately before the HTML generation, but that's still better than having an HTML block contain SQL queries right in the middle of it. 我的示例通过在紧接HTML生成之前使用SQL来将其关闭,但这仍然比在其中间包含SQL查询的HTML块更好。

Have you run that query in a MySQL tool to see how long it takes? 您是否已在MySQL工具中运行该查询以查看需要多长时间?

Do you have an index on the author column? 在作者列上有索引吗?

There's nothing wrong with your PHP. 您的PHP没错。 I suspect the query is the problem and no index is the cause. 我怀疑查询是问题所在,没有索引是原因。

aside from their comments above, also try to optimize your sql query since this is one of the most common source of performance issues. 除了上面的评论外,还请尝试优化SQL查询,因为这是性能问题的最常见来源之一。

let say you have a news article table with Title, Date, Blurb, Content fields and you only need to fetch the title and display them as a list on the html page, 假设您有一个新闻文章表,其中包含标题,日期,模糊,内容字段,而您只需要获取标题并将它们显示为html页面上的列表,

to do a " SELECT * FROM TABLE " means that you are requiring the db server to fetch all the field data when doing the loop (including the Blurb and Content which you are not going to use). 执行“ SELECT * FROM TABLE ”意味着您需要db服务器在执行循环时获取所有字段数据(包括您将不使用的Blurb和Content)。

if you optimize that to something like: 如果您将其优化为:

" SELECT Title, Date FROM TABLE " would fetch only the necessary data and would be more efficient in terms of server utilization. SELECT Title,Date FROM TABLE ”将仅获取必要的数据,并且在服务器利用率方面将更加有效。

i hope this helps you. 我希望这可以帮助你。

Is 'author' an id? “作者”是一个ID吗? or a string? 还是一个字符串? Either way an index would help you. 无论哪种方式,索引都会对您有所帮助。

The query is not slow, its the for loop thats causing the problem. 查询不是很慢,它的for循环就是问题所在。 Its not complete; 它不完整; missing the $i loop condition and increment. 缺少$ i循环条件和增量。 Or is this a typo? 还是这是错字?

Why don't you just order the query by the date? 为什么不按日期排序查询呢?

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

and have a variable to store the current date you are on to have any logic required to group events by date in your table ex. 并具有一个变量来存储当前日期,以便具有在表ex中按日期对事件进行分组所需的任何逻辑。 giving all event rows with the same date the same color. 为所有具有相同日期的事件行提供相同的颜色。

Assuming the date is a unix timestamp that does not account for the event's time then you can do this: 假设日期是一个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'];
}

if unixdate includes the event time, then you need to add some logic to just extract the unix date timestmap excluding the hours and minutes. 如果unixdate包括事件时间,那么您需要添加一些逻辑以仅提取unix日期时间戳表(不包括小时和分钟)。

Hope that helps 希望能有所帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM