我想知道在我的应用程序中加速公司导出功能的最佳方法是什么:
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'));
}
所以它的作用是搜索数据库中符合特定条件的公司。然后将结果设置为能够在相应的视图中显示。
如何加快此功能?您想要导出的结果越多,导出它们所需的时间就越多,但是可以通过某种方式对其进行优化吗?目前只需要大约30秒就可以导出4000个结果 - 所以我不认为它能够导出40000个结果并且它应该可以吗?这是服务器的问题吗?
感谢。
答案 0 :(得分:1)
这不是服务器的问题,而是程序架构的问题。
由于您已遇到的明显原因,您不想动态获取和呈现大量信息。
我对您的应用程序的要求知之甚少,但我认为您需要下载报告。 假设它必须始终是最新的这就是我要做的事情:
用户点击链接下载报告。用户将显示加载指示符,并且正在使用JS和AJAX准备报告导出的消息。在服务器端,触发任务以构建报告。
后台服务,一个在循环中运行的简单CakePHP shell,会注意到有一个新的报告要构建。它将构建报告以块的形式读取db记录以避免内存不足并将其写入文件。完成后,报告下载请求将标记为已完成,并且可以下载文件。在客户端,长轮询JS脚本注意到该文件已准备好并下载它。
另一个解决方案,假设数据不一定是最新的,将是每天生成一次报告文件,并让它们可供下载而无需等待用户。在服务器端,任务将保持不变:以块的形式读取和写入数据。
关于问题的效果部分:
这不会让它变得更快,但它会给用户一个反馈,你甚至可以根据已处理的块计算(估计)剩余时间,并进一步防止脚本因内存不足而崩溃。 您可以直接将文件流式传输到客户端,而不是将文件写入磁盘。一旦开始读取第一个块,您就会开始发送数据。但是从数据库中读取数据......好好把钱和硬件扔在上面。如果你有钱,我建议你使用带有SSD的RAID5阵列。期待投入数千美元。
但即使是最快的数据库读取也受限于您可以发送的带宽以及用户可以接收的带宽。为了加速数据库,我建议您在superuser.com上询问,我不是数据库硬件的专家,但正确设置的SSD配置可以大大提高数据库的速度。
仅提取您需要的数据:
我在您的查找中没有看到任何contains()或递归设置:确保您只获取报告中真正需要的数据!