簡體   English   中英

PHP 5中的輸出緩沖和大型MySQL結果集

[英]Output buffering and large MySQL result sets in PHP 5

我正在嘗試從具有巨大表,近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);

請幫助?

謝謝

Midiane。

可能是您查詢的速度很慢?
比較輸出

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";
}

使用EXPLAIN優化查詢

您可以使用set_time_limit(0)來使腳本永久運行而沒有任何超時,並等待其完成執行。

超時幾乎肯定會發生,因為您的查詢很慢-通過確保索引正確的列並執行一些JOIN,幾乎可以肯定會提高其性能。

如果您重寫查詢結構,該怎么辦:

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

確保所有外鍵列(j.location_id等)都已建立索引。

如果您希望輸出更快開始,則需要-查詢數據庫-輸出所有標頭,等等。-將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:我還注意到您在SO上還有另一個與SQL有關的問題。 我認為,更好地了解SQL的工作原理將為您提供很好的服務。 我強烈建議您獲取一份“ SLQ明確說明 ”的副本-它准確地提供了標題所承諾的內容-對SQL的明確解釋(通常,不要陷入討論各種實現的困惑)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM