通过循环 AJAX 或服务器端调用繁重的 PHP 函数

Call a heavy PHP function through a loop AJAX or server-side

选择服务器端和客户端哪个最好? 我有一个 PHP 函数,类似于:

function insert(argument)
{
   //do some heavy MySQL work such as sp_call
   // that takes near about 1.5 seconds  

}

我必须调用这个函数大约 500 次。

for(i=1;i<=500;i++)
{
  insert(argument);
}

我有两个选择:

a) call through loop in PHP(server-side)-->server may timed out 
b) call through loop in JavaScript(AJAX)-->takes a long time.

如果有第三个,请推荐最好的

如果我理解正确,你的服务器仍然需要做所有的工作,所以你不能使用客户端计算机来减少服务器所需的功率,所以你可以选择以下选项:

  1. 让客户端询问服务器500次。这将很容易让您向客户展示流程,让他满意地知道事情正在发生,或者

  2. 让服务器做所有事情来跳过额外的 500 次往返时间,以及处理 500 次请求所需的额外开销。

如果客户不早点放弃并不重要,我可能会选择 1,或者如果工作一直完成很重要,我可能会选择 2,因为客户可能会在 300 后停止请求.

编辑:关于您的评论,我建议在客户端设置一个 "start work" 按钮,告诉服务器开始作业。然后您的服务器告诉后台服务(可以在 php 中创建)来完成这项工作。它可以将其过程更新到文件或数据库或其他内容中。然后客户端和 php 服务器可以自由超时并没有问题地注销。然后您可以更新页面以查看工作是否在后台完成,这可以从数据库或文件或其他任何地方收集。然后你最大限度地减少时间和依赖性。

您没有给出您要实现的目标的任何上下文 - 这里最重要的是性能以及是否应将一组值视为单个事务。

循环距离物理存储(不仅仅是 DBMS)越远,对性能的影响就越大。对于大多数 web 应用程序,最大的性能瓶颈是客户端和 web 服务器之间的网络延迟——即使你相对较近......比如 50 毫秒......并且让 keeaplives 正常工作,那么它至少需要 25 秒对 500 个数据项执行此操作。

为了获得最佳性能,您应该以最少数量的 DML 语句将数据发送到 DBMS - 您已经提到 MySQL 在同一个数据库调用中支持 multiple row inserts and if you're using MySQLi you can also submit multiple DML statements(尽管后者只是消除了 PHP 和 DBMS 之间的干扰,而插入多行的单个 DML 也减少了 DBMS 和存储之间的干扰)。根据数据结构和优化,这应该在 10 毫秒左右的时间内插入数百行——这两种方法都会比在客户端中使用循环 运行 快得多,即使延迟为 0。

交易进行中的时间长度将决定交易失败的可能性 - 因此,更快的方法比 Ajax 方法可靠数千倍。

正如 Krycke 所建议的那样,使用客户端来完成一些工作不会节省您系统上的资源 - 网络服务器、PHP 个实例和 DBMS 连接会产生额外的开销。尽管这些相对较小,但它们加起来很快。如果您测试这两种方法,您会发现在 PHP 或数据库中使用循环会显着减少工作量,从而增加服务器的容量。

有一次我的剧本是 运行 几十分钟。我的解决方案是通过 AJAX 进行长请求,超时 1 秒,并在另一个 AJAX 线程中检查结果。用户体验好于在没有 ajax.

的情况下等待 php 响应太久

$.ajax({
  ...
  timeout: 1000
})

所以我终于明白了。

a) 如果您想确定它会完成,请使用 AJAX。它也是用户友好的,因为他在 AJAX 次通话之间得到定期回复。

b) 如果您几乎确定服务器不会在两者之间停止运行并且希望减少客户端的负载,请使用服务器端脚本。

现在我正在使用服务器端脚本和等待消息 window 给用户,用户等待成功提交消息,否则他必须重试。 第一次尝试成功的概率为 90-95%。