0

我有一个 nginx+PHP+MySQL 服务器。MySQL 有一个包含作业的大型数据库。我正在运行的 PHP 脚本应该从数据库中检索所有作业并输出包含所有作业的 XML 提要。脚本目前是这样组织的

$arr = get_all_job_ids(); //returns 18k PHP array that is fueled by SELECT `id` FROM `jobs`;
foreach ($arr as $i=>$id){
    if ($i>9700){break;} //for debugging
    $job = get_job_by_id($id); //PHP array generated by SELECT `title`, desc, ... FROM `jobs` WHERE `id`=$id;
    $job_xml = replace_job_tags($job, $xml_template); //regular expressions
    echo $job_xml;
    flush();
}

服务器上没有任何人,它只专用于实验,没有其他任何东西在上面运行。首先,即使我做了一些事情,比如释放 sql 结果并明确清理 PHP 可能没有清理的任何内容,总体内存消耗在循环中不断增长。它在 flush() 之后下降,但没有回到迭代开始时的水平。

其次,更重要的是 - 运行时间和 CPU 负载完全不一致。有时可以在 17 秒内很好地生成 9.7k 的作业提要。在这些情况下,根据“top”和“SHOW FULL PROCESSLIST;” 在 get_all_job_ids() 步骤期间 CPU 会短暂飙升至 100%,但随后会平静下来并花时间逐一检索和刷新()作业。

但在其他时候,php5-fpm 和 mysqld 在初始 id 检索步骤和单个作业的循环查询期间为自己获取所有 CPU。此外,即使根据“SHOW FULL PROCESSLIST;” 正在查询单个作业,http 客户端从未获得任何输出,而是最终收到“504 网关超时”。经过较长时间(分钟)后mysqld和php5-fpm恢复正常。此外,当我排除 get_job_by_id() 步骤并在那里硬编码一个数组时,一切都运行良好且顺利。

我完全不知道是什么导致了这种情况,以及我还可以尝试进一步阐明这个问题。如果您有任何想法,我会很高兴听到它们!

4

1 回答 1

0

为什么你需要执行“SELECT id FROM foo”然后“SELECT ... FROM foo where id = ...” - 这里的大问题是,这必须在一个查询中完成

于 2012-11-30T20:57:39.433 回答