【发布时间】:2011-08-23 20:48:40
【问题描述】:
长话短说,如果我将 PHP 脚本分解成小块,我最终可以运行所有代码。但是,我现在有一个脚本,它读取一个巨大的 CSV 文件并将每一行插入到 MySQL 数据库中。每次我想更新我的网站时,我都不必经历拆分文件的繁重过程,我只想让这个脚本按照我知道的方式工作。
我之前已经让它在不同的网络服务器上插入大约 10,000 行,但文件中至少有 7 倍,而且它在完成之前就崩溃了。
因此,故事是,在一台服务器上它在它应该停止之前停止,而在另一台服务器上它根本不运行......它只是在大约 30 秒后突然出现 500 错误。
当脚本终止时,Apache 错误日志给了我这些行:
[Tue Aug 23 13:09:04 2011] [warn] [client 71.168.85.72] mod_fcgid: read data timeout in 40 seconds
[Tue Aug 23 13:09:04 2011] [error] [client 71.168.85.72] Premature end of script headers: newcsvupdater.php
我在脚本的顶部有这两行:
set_time_limit(0);
ini_set('memory_limit','256M');
因为之前我遇到了致命的内存分配错误,因为显然将大文件拆分为数组会占用大量内存。
这是插入代码:
$file = "./bigdumbfile.csv"; // roughly 30mb
$handle = fopen($file, r);
$firstentry = 0;
while($csv = fgetcsv($handle))
{
if($firstentry == 0)
{
$firstentry++; // skips the top row of field names
}
else
{
// unimportant conditional code omitted
$checkforexisting = mysql_query("SELECT * FROM DB_TABLE WHERE ".
"id_one = '".$csv[0]."' AND id_two = '".$csv[2]."'");
$checknum = mysql_num_rows($checkforexisting);
if($checknum == 0)
{
if(!mysql_query("INSERT INTO DB_TABLE ".
"(id_one, data_one, id_two, data_two, ".
/* so on for 22 total fields */")
VALUES ('".addslashes($csv[0])."', '".
addslashes($csv[1])."', '".
addslashes($csv[2])."', '".
addslashes($csv[3])."' "/* ditto, as above */))
{
exit("<br>" . mysql_error());
}
else
{
print_r($csv);
echo " insert complete<br><br>";
}
}
}
}
echo "<br><b>DB_TABLE UPDATED";
我以前因此不得不拆分大型任务,我已经厌倦了。我敢肯定我做错了很多,因为我完全是自学成才的,而且通常写的东西相当于意大利面,所以不要退缩。
【问题讨论】:
-
如果您已经超过了 40 秒的超时时间,那么您需要弄清楚为什么您的脚本如此缓慢并可能执行其他操作。我有一个导入大型 mysql 数据库的脚本。我用它在 3 小时内导入了一个 10GB 的数据库。