[英]Output buffering and large MySQL result sets in PHP 5
I'm trying to build an XML feed from a database with a ginormous table, almost 4k records. 我正在尝试从具有巨大表,近4k记录的数据库中构建XML提要。 I want to use output buffering to get it to spit out the XML but the script still keeps on timing out. 我想使用输出缓冲来使其吐出XML,但脚本仍会继续超时。
ob_start();
$what = 'j.*, (select description from tb_job_type as jt WHERE jt.jobtype_id = j.job_type_id) as job_type,';
$what .= '(select description from tb_location as l WHERE l.location_id = j.location_id) as location,';
$what .= '(select description from tb_industry as i WHERE i.industry_id = j.industry_id) as industry';
$where = ('' != $SelectedType) ? 'j.job_ad_type="' . $SelectedType .'"' : '';
$process = $db->executeQuery('SELECT ' . $what . ' FROM tb_job_ad as j' . $where);
while($result = mysql_fetch_array($process))
{
$result['job_title_url'] = $form->urlString($result['job_title']);
$result['job_title'] = htmlspecialchars($result['job_title'], ENT_QUOTES, 'UTF-8');
$result['short_description'] = htmlspecialchars($result['short_description'], ENT_QUOTES, 'UTF-8');
$result['full_description'] = htmlspecialchars($result['full_description'], ENT_QUOTES, 'UTF-8');
$result['company_name'] = ucwords(strtolower($result['company_name']));
$tpl->assignToBlock('ITEMS', $result);
}
$cheese = ob_get_contents();
$actualize = $tpl->actualize('FEED');
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT" );
header("Last-Modified: " . gmdate( "D, d M Y H:i:s" ) . "GMT" );
header("Cache-Control: no-cache, must-revalidate" );
header("Pragma: no-cache" );
header("Content-type: text/xml");
echo $actualize;
ob_flush();
print $cheese;
ob_end_clean();
This seems to be the line that makes the script choke: 这似乎是导致脚本阻塞的行:
$tpl->assignToBlock('ITEMS', $result);
Help please? 请帮助?
Thanks 谢谢
Midiane. Midiane。
Could it be that you have a rather slow query? 可能是您查询的速度很慢?
Compare the output of 比较输出
set_time_limit(60);
$process = $db->executeQuery('EXPLAIN SELECT ' . $what . ' FROM tb_job_ad as j' . $where);
while($result = mysql_fetch_array($process, MYSQL_ASSOC)) {
echo join(' | ', $result), "<br />\n";
}
您可以使用set_time_limit(0)来使脚本永久运行而没有任何超时,并等待其完成执行。
The timeout is almost certainly happening because your query is slow -- and you could almost certainly improve it's performance by making sure you've got the right columns indexed, and doing some JOINs. 超时几乎肯定会发生,因为您的查询很慢-通过确保索引正确的列并执行一些JOIN,几乎可以肯定会提高其性能。
What if you rewrote you query construction like this: 如果您重写查询结构,该怎么办:
$q = 'SELECT
j.*,
jt.description as job_type,
l.description as location,
i.description as industry
FROM tb_jobs AS j
INNER JOIN tb_job_type AS jt ON j.job_type_id = jt.jobtype_id
INNER JOIN tb_location AS l ON j.location_id = l.location_id
INNER JOIN tb_industry AS i ON j.indsutry_id = i.industry_id';
if (! empty($SelectedType)){
$where = "WHERE j.job_ad_type = '$SelectedType'";
}else{
$where = '';
}
$q .= $where;
Make sure that all your foreign keys columns (j.location_id, etc) are indexed. 确保所有外键列(j.location_id等)都已建立索引。
If you want output to start sooner, you'll want to - Query the database - Output all your headers, etc. - write you while loop like: 如果您希望输出更快开始,则需要-查询数据库-输出所有标头,等等。-将while循环写为:
ob_end_flush();flush();
while($row = mysql_fetch_assoc($process)
{
ob_start();
//build your ITEM and echo it here
ob_end_flush(); flush();
}
PS: I also noticed another SQL-Related question of yours here on SO. PS:我还注意到您在SO上还有另一个与SQL有关的问题。 I think you'd be very well served by gaining a better understanding of how SQL works. 我认为,更好地了解SQL的工作原理将为您提供很好的服务。 I highly recommend getting a copy of " SLQ Clearly Explained " -- it delivers exactly what the title promises -- a clear explanation of SQL (in general, without getting bogged down discussing various implementations) 我强烈建议您获取一份“ SLQ明确说明 ”的副本-它准确地提供了标题所承诺的内容-对SQL的明确解释(通常,不要陷入讨论各种实现的困惑)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.