PHP 5 中的输出缓冲和大型 MySQL 结果集
我正在尝试从具有巨大表(几乎有 4k 条记录)的数据库构建 XML 提要。我想使用输出缓冲来让它吐出 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();
这似乎是让脚本窒息的那行:
$tpl->assignToBlock('ITEMS', $result);
请帮忙?
谢谢米黛安
。
I'm trying to build an XML feed from a database with a ginormous table, almost 4k records. I want to use output buffering to get it to spit out the XML but the script still keeps on timing out.
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
是否您的查询速度相当慢?
的输出。
比较使用 EXPLAIN 优化查询
Could it be that you have a rather slow query?
Compare the output of
with Optimizing Queries with EXPLAIN.
您可以使用 set_time_limit(0) 允许脚本永远运行而不会超时,并等待其完成执行。
You can use set_time_limit(0) to allow your script to run forever without any timeout and wait until it completes execution.
超时几乎肯定会发生,因为您的查询速度很慢,而且您几乎肯定可以通过确保对正确的列进行索引并执行一些联接来提高其性能。
如果您像这样重写查询构造会怎样:
确保所有外键列(j.location_id 等)都已建立索引。
如果您希望更快地开始输出,您需要
- 查询数据库
- 输出所有的标题等。
- 写给你 while 循环:
PS:我还注意到你在这里提出的另一个与 SQL 相关的问题。我认为更好地理解 SQL 的工作原理会对您大有裨益。我强烈建议您获取一份“SLQ 清晰解释”——它提供了正是标题所承诺的——对 SQL 的清晰解释(一般来说,不会陷入讨论各种实现的困境)
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.
What if you rewrote you query construction like this:
Make sure that all your foreign keys columns (j.location_id, etc) are indexed.
If you want output to start sooner, you'll want to
- Query the database
- Output all your headers, etc.
- write you while loop like:
PS: I also noticed another SQL-Related question of yours here on SO. I think you'd be very well served by gaining a better understanding of how SQL works. 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)