0

我想知道在我的应用程序中加速公司导出功能的最佳方法是什么:

function export(){
    ini_set('memory_limit', '-1');
    ini_set('max_execution_time', 0);

    $conditions = $this->getConditions($this->data);
    $resultCompanies = $this->Company->find('all', array('conditions' => $conditions));

    $this->set(compact('resultCompanies'));
}

所以它的作用是在数据库中搜索符合特定条件的公司。然后将结果设置为能够显示在相应的视图中。

我怎样才能加快这个功能?您想要导出的结果越多,导出它们所需的时间就越多,但是否可以通过某种方式对其进行优化?目前仅导出 4000 个结果大约需要 30 秒 - 所以我不认为它能够导出 40000 个结果,它应该能够吗?是服务器的问题吗?

谢谢。

4

1 回答 1

1

这不是服务器的问题,而是程序架构的问题。

由于您已经遇到的明显原因,您不想即时获取和呈现大量信息。

我对您的应用程序的要求知之甚少,但我认为您需要下载一份报告。假设它必须始终是最新的,我会这样做:

用户单击链接以下载报告。用户将看到一个加载指示器,并显示正在使用 JS 和 AJAX 准备报告导出的消息。在服务器端触发任务以构建报告。

一个后台服务,一个循环运行的简单 CakePHP shell,会注意到有一个新的报告要构建。它将构建以块读取数据库记录的报告,以避免内存不足并将其写入文件。完成后,报告下载请求被标记为完成,并且可以下载文件。在客户端,长轮询 JS 脚本注意到文件已准备好并下载它。

另一种解决方案,假设数据不必是最新的,例如,每天生成一次报告文件,并让它们可供下载,而无需用户等待。在服务器端,任务将保持不变:以块的形式读取和写入数据。

关于问题的性能部分:

它不会让它更快,但它会给用户一个反馈,你甚至可以根据已经处理的块计算(估计)剩余时间,并进一步防止脚本因内存不足而崩溃。您可以直接将文件流式传输到客户端,而不是将文件写入磁盘。一旦它开始读取第一个块,您将开始发送数据。但是从数据库中读取数据......好吧,在上面投入金钱和硬件。如果您有钱,我建议您使用带有 SSD 的 RAID5 阵列。期望在它上面投入几千美元。

但即使是最快的数据库读取也受到您可以发送和用户可以接收的带宽的限制。为了加速数据库,我建议您在 superuser.com 上询问,我不是数据库硬件专家,但正确设置的 SSD 配置可以极大地提高您的数据库速度。

仅获取您需要的数据:

我在您的发现中没有看到任何包含()或递归设置:确保您只获取报告中真正需要的数据!

于 2013-08-13T13:39:07.563 回答