我的PHP脚本在运行时会出现500个内部服务器错误
长话短说,如果我把一个PHP脚本分成小块,我最终可以运行我所有的代码。然而,我现在有一个脚本,它读取一个巨大的CSV文件,并将每一行插入MySQL数据库。每次我想更新我的站点时,我不必经历分割文件的繁重过程,我只想让这个脚本按照我所知道的方式工作 我已经让它在不同的web服务器上插入了大约10000行,但是在文件中至少有7倍的行,而且在它完成之前就已经废弃了 所以,故事是,在一台服务器上,它在应该停止之前停止,而在另一台服务器上,它根本不运行。。。大约30秒后,它突然出现了500个错误 当脚本终止时,Apache错误日志为我提供了以下几行代码:我的PHP脚本在运行时会出现500个内部服务器错误,php,mysql,apache,Php,Mysql,Apache,长话短说,如果我把一个PHP脚本分成小块,我最终可以运行我所有的代码。然而,我现在有一个脚本,它读取一个巨大的CSV文件,并将每一行插入MySQL数据库。每次我想更新我的站点时,我不必经历分割文件的繁重过程,我只想让这个脚本按照我所知道的方式工作 我已经让它在不同的web服务器上插入了大约10000行,但是在文件中至少有7倍的行,而且在它完成之前就已经废弃了 所以,故事是,在一台服务器上,它在应该停止之前停止,而在另一台服务器上,它根本不运行。。。大约30秒后,它突然出现了500个错误 当脚本终
[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";
因为这个原因,我以前不得不把大任务分开,我对此感到非常厌倦。我肯定我做错了很多,因为我完全自学成才,通常写的都是意大利面,所以不要犹豫。您可以使用SQL插入成批的值,这将减少查询运行往返所需的时间,这可能是您的瓶颈
INSERT INTO table (cola,colb...)
VALUES
(vala,valb...),
(valc,vald...)
大多数情况下,当您执行像这样的大型插入时,您希望异步执行,这意味着您将文件转储到某个位置,脱机处理它,然后通知用户该文件已完成,而不是等待页面加载完成
我还看到,在你真正插入之前,你正在检查是否存在。您可能需要考虑选择可能匹配的行,然后使用哈希进行PHP侧的检查,而不是每次运行该查询。
看来,您对APACHE的超时不是在PHP上。
set_time_limit函数用于php脚本,apache对此一无所知。我的第一反应是在不使用php或更好的情况下完成所有这些
要增加脚本的时间限制,您需要编辑站点的虚拟主机配置: mod_fcgid的超时正在覆盖PHP的超时 若要加快脚本速度,以便您可能不需要执行上述步骤(在共享主机上可能无法执行),请尝试以下操作: 准备好要在advanced中插入的所有信息以进行批量插入。查询应如下所示:
INSERT IGNORE INTO (id_one, data_one, id_two, data_two) VALUES
(1, 'apple', 3, 'banana'),
(4, 'pear', 5, 'orange)
“忽略”部分应该具有预先检查记录是否已存在的相同效果。如果记录已存在,则不会插入该记录,并将继续下一个记录。如果超过40秒的超时时间,则由您自己决定脚本为何如此慢,并可能执行其他操作。我有一个导入大型mysql数据库的脚本。我用它在3小时内导入了一个10GB的数据库。不仅如此,MySQL还可以直接读取CSV文件。没有真正的理由尝试用PHP编写它,除非您编写的导入脚本允许用户为导入的CSV文件设置自己的标题名。有人希望使用PHP来处理CSV,而不是直接将其输入数据库,这有十几个原因。删除检查重复条目的查询可以让脚本快速、完美地运行。我想从现在开始我们要做的是备份表,清空它,然后再把整个文件放上去。另一方面,我昨晚做了一道美味的意大利面酱。。。
INSERT IGNORE INTO (id_one, data_one, id_two, data_two) VALUES
(1, 'apple', 3, 'banana'),
(4, 'pear', 5, 'orange)