通过AJAX处理大型数据集不会带来速度上的好处


Processing large data sets via AJAX brings no speed benefits

我有几个耗时的数据库查询要运行。每个都被构建为从网页上选择的选项触发。我认为我通过几个AJAX请求来完成工作是相当狡猾的。

我假定多个请求将被分配到多个进程/线程中,这意味着工作将相对较快地为用户完成。

然而,请求似乎是串行处理的,这意味着用户感觉不到速度优势。

更糟糕的是,更新页面的AJAX请求也排队等待,这意味着它们在之前的请求全部完成之前无法响应。

我了解到这可能是由于PHP会话被锁定引起的。

通常处理这种问题的方法是什么?

    是否有一种方法可以强制AJAX请求异步工作?
  • 我可以阻止PHP锁定会话吗?
  • 我应该通过cron使用一个单独的进程来触发后台工作吗?

谢谢!

注意:这个项目是使用symfony框架构建的。

AJAX使用jQuery

// Get the content
$.get('/ajax/itemInformation/slug/'+slug, function(data) {
  $('#modal-more-information').html(data);
});

如果在任何给定的AJAX请求期间使用会话,则它们将有效地按请求顺序串行执行。这是由于会话数据文件在操作系统级别被锁定。使这些请求异步的关键是尽可能快地关闭(或永远不启动)会话。

您可以使用session_write_close (docs)尽快关闭会话。为此,我喜欢使用几个辅助函数,下面的set_session_var函数将打开会话,写入var,然后关闭会话-尽可能快地进出。当页面加载时,您可以调用session_start来填充$_SESSION变量,然后立即调用session_write_close。从此以后,只使用下面的set函数来写。

get函数是完全可选的,因为您可以简单地引用$_SESSION全局变量,但我喜欢使用它,因为它提供了一个默认值,并且我可以在代码主体中少一个三进制。

function get_session_var($key=false, $default=null) {
    if ($key == false || strlen($key) < 0)
        return false;
    if (isset($_SESSION[$key]))
        $ret = $_SESSION[$key];
    else
        $ret = $default;
    return $ret;
}
function set_session_var($key=false, $value=null) {
    if ($key == false || strlen($key) < 0)
        return false;
    session_start();
    if ($value === null)
        unset($_SESSION[$key]);
    else
        $_SESSION[$key] = $value;
    session_write_close();
}

请注意,一旦AJAX请求是真正异步的,就会有一整套新的考虑事项。现在您必须注意竞争条件(您必须警惕一个请求设置了一个可能影响另一个请求的变量)—因为您可以看到,当会话关闭时,一个请求对$_SESSION的更改对于另一个请求将不可见,直到它重新构建值。您可以通过在关键使用之前立即"重建"$_SESSION变量来帮助避免这种情况:

function rebuild_session() {
    session_start();
    session_write_close();
}

…但是这仍然容易受到竞争条件的影响。