2

我有一个 PHP 脚本,它将使用 PHPExcel 从 MySQL DB 查询的数据生成报告。目前,它的处理是线性的,它从 MySQL 获取数据,读入 Excel 模板,将数据写入模板,然后输出。我已经优化了代码,使得数据只迭代一次,并且在 PHP 端进行的处理很少。该查询在 0.001 秒内返回数百行,因此运行速度足够快。经过一段时间后,我发现我的瓶颈是(惊讶,惊讶)读取模板并写入输出。我想这样做:

Spawn a thread/process to read the template
Spawn a thread/process to fetch the data
Return back to parent thread - Parent thread will wait until both are complete
Proceed on as normal

我的主要问题是这可能吗,值得吗?如果两者都是,您将如何解决?此外,它是 CentOS 上的 PHP 5

4

6 回答 6

8

fork Apache 进程通常不是一个好主意。这可能会导致不确定的结果。相反,最好使用某种排队机制。Gearman 是您可以使用的开源队列机制。我还有一篇关于 Zend Server Job Queue 的博文,讨论了异步运行任务你排队吗?Zend 服务器作业队列简介

您还可以使用 Zend Framework Queuing 类之类的东西来实现一些异步工作。 Zend_Queue

@Swisstack,我也不同意您的断言,即 PHP 不是为高性能而创建的。语言特性很少会导致性能下降。也许通过在不同语言之间进行比较 $a++ 的原始语言测试,您会看到这一点,但这种类型的测试是无关紧要的。我已经在 PHP 上进行了几年的咨询,但我从未见过由于该语言而导致的性能问题。

于 2010-04-20T21:49:39.323 回答
1

我会尝试弄清楚您是否可以以更快的阅读格式缓存或存储模板。我不知道这是否可能,但 PHPExcel 论坛非常好,并且受到开发人员的关注。

于 2010-04-20T21:30:32.657 回答
1

你不能多线程,但你可以分叉(pcntl_forkpcntl_wait)。我肯定知道,您需要仔细测试进程生成时间,以确保这对于您的情况来说是值得的。

$pid = pcntl_fork();

if ($pid == -1) {
  // fork failed

} elseif ($pid > 0) {
  // we're the parent! Wait for child to finish
  pcntl_waitpid($pid);

} else {
  // we're the child
}
于 2010-04-20T21:33:40.153 回答
1

如果读取模板和数据库查询都很慢,那么我会说通过并行运行任务可以获得有价值的性能的机会很大。但是,你自己说,读模板慢,db查询快。因此,即使忽略由并行运行任务所需的添加所带来的任何额外开销,在最好的情况下,您也可以节省 0.001 秒(数据库查询所需的时间)。

并行运行多个任务总是需要最慢任务的时间。串行运行任务是所有任务的总和。在您的情况下, templateTime + queryTime(0.001)

不值得我。

通常数据库是方程中的乌龟。您可以毫不费力地异步完成该部分。查看新添加的 mysqli_poll() 和友元函数。

于 2010-04-20T22:05:45.807 回答
0

您绝对可以使用 PHP ( http://php.net/manual/en/function.pcntl-fork.php ) 在 CentOS 上生成进程。不过,在这样做之前,我至少会考虑一件事......如果瓶颈似乎是在读取模板和写入输出时,它可能只是一个 I/O 绑定问题,因此处理多个进程可能没有多大帮助...就我个人而言,我会尝试看看是否可以进行一些缓存...

于 2010-04-20T21:33:13.737 回答
0

阅读模板一次,然后为您需要从数据创建的每个工作簿进行克隆

于 2010-04-26T18:59:09.097 回答