每隔三个月,我需要上传一个包含约40万种产品的CSV文件,并将其插入MySQL数据库。我觉得我的方法不太有效,并希望提出一些建议。
目前,我像这样解析CSV文件:
public function parse_csv_to_array() {
// Initialize empty array
$array = $fields = array();
$interval = 0;
// File Handle
$handle = @fopen($this->csvFile, "r");
if ($handle) {
while (($row = fgetcsv($handle, 4096)) !== false) {
if (empty($fields)) {
$fields = $row;
continue;
}
foreach ($row as $k=>$value) {
$array[$interval][$fields[$k]] = $value;
}
$interval++;
}
if (!feof($handle)) {
echo "Error: unexpected fgets() fail\n";
}
fclose($handle);
}
return $array;
}
然后,我简单地遍历数组,以插入新记录或替换现有记录(如果已存在)。这意味着我要执行至少120万个SQL查询,以首先检查记录是否存在,然后将记录插入/替换到数据库中。
当前,这是作为HTML5表单上传完成的,并且在用户单击提交后在用户浏览器中执行。整个过程最多可能需要30分钟,我认为这还不错,但是我不得不将PHP脚本的超时设置为无限制,以允许脚本运行。我觉得这不是非常有效,并且会大大增加服务器的负载。我想知道是否有分割数组并将记录上载到分区中的方法,还是应该使用CRON这样的调度程序。仅在一个脚本中执行120万个SQL查询的想法让人感到肮脏,因此必须有一种更好的方法。任何建议都将受到欢迎。
答案 0 :(得分:0)
您可以执行一次查询以取回所有记录,将记录存储在数组中,将csv中的数据与数组中的值进行比较,并在必要时进行更新。您还可以创建仅包含需要更新的值的数组,然后进行批量插入。
在这种方法中,您对数据库的请求不多,因此,它的资源消耗应较少。
答案 1 :(得分:0)
我认为使用块和cron将是最好的解决方案。每隔几分钟运行一次cron,以查找新数据并将其上载到数据库(如果有的话)。然后它可以在后台运行。
要加快脚本本身的速度,您还可以对条目和diff进行分块并批量插入。然后,您不必做太多的sql语句。