【发布时间】:2014-12-19 02:26:34
【问题描述】:
我有一个用 PHP 构建的 LAMP 网站。我有一个像http://myproject.com/report-download.php 这样的页面,上面有一个按钮,上面写着Export CSV。当用户点击按钮时,他们会得到一个 csv 文件,其中包含一些最初在 MySQL 数据库中的报告数据。当我只有几条记录时,这很有效。但是当我有 100 万条记录时,页面抓取数据并创建 csv 文件需要更长的时间。在此 CSV 创建期间,用户在网站上从一个页面转到另一个页面需要很长时间。
当 Web 服务器仍在生成 CSV 时,PHP 开发人员通常如何解决页面加载缓慢的问题?我可以通过 PHP 线程解决这个问题吗?或者我应该对 apache 做些什么?
加法
I create the csv file kinda like this
while($row = $db->getData($pageNumber))
{
add_to_file('file.csv.inprogress',array_to_csv($row));
$pageNumber++;
}
header("Content-type: text/csv");
header("Content-Disposition: attachment; filename=file.csv");
header("Pragma: no-cache");
header("Expires: 0");
echo file_get_contents('file.csv.inprogress');
但是创建 csv 文件需要很长时间,所以在这段时间内,页面加载时间对于用户来说确实很慢。
【问题讨论】:
-
我们缓存。您可能想要投资 memcached 或 redis 实例并在那里缓存数据。此外,保存报告,以便在下一个请求相同时,您只需提供已生成的文件。
-
php 没有原生线程。 “真的很长”?如果您使用会话,则会话被当前正在运行的脚本锁定。在进入任何长时间运行的代码部分之前尝试
session_write_close(),这样锁就会被释放并且可以查看其他页面。 -
我唯一一次遇到服务器在文件写入过程中运行缓慢的问题,我升级到了固态驱动器。问题现在消失了:p 有很多方法可以解决这个问题,但是在可以缓存的页面上添加缓存会有所帮助。我不一定会认为这是一个编程问题,但更多的是服务器管理/硬件/配置问题 - 我的两分钱。
-
如果报告需要很长时间才能生成并且不适合缓存,您始终可以使用后端 shell 进程生成它,并在完成后让客户端回来获取它。如果生成的数据库负载太高,您可以考虑维护一个只读数据库镜像以生成报告。
-
如果您只是在谈论为其生成 csv 的用户的页面加载时间,那么使用 ajax 进行异步调用可能会有所帮助。