使用mysql加载数据infile处理大型csv文件

时间:2017-01-08 17:10:22

标签: php mysql csv pdo laravel-5.3

我正在尝试读取包含500k行和81列的CSV文件并将其插入数据库中。 CSV大小为160 MB。我必须每3-4小时处理一次。每3-4个小时我会有一个新的CSV,其中包含一些新记录和一些现有记录。为此我遵循了许多方法,但没有任何完美的工作。

方法1 :它会读取所有记录,但需要花费太多时间。读取200k记录然后超时需要1个多小时。

$file    = fopen($path, 'r');
while (($line = fgetcsv($file)) !== FALSE) {
}

作为解决方案:我可以增加php限制,执行时间和内存限制以避免此错误,但我觉得它很慢。

方法2:

$query = "LOAD DATA LOCAL INFILE products.csv INTO TABLE tmp_tbl LINES TERMINATED BY '\\r\\n' FIELDS TERMINATED BY ',' IGNORE 1 LINES";

DB::select($query);

它出现了以下错误。

  

SQLSTATE [42000]:语法错误或访问冲突:1064您有   SQL语法错误;查看与您的手册相对应的手册   MariaDB服务器版本,用于在'FIELDS附近使用正确的语法   终止于','IGNORE 1 LINES'在第1行(SQL:LOAD DATA LOCAL   INFILE'products.csv'INTO表tmp_tbl由'\ r \ n'终止的行   字段被','IGNORE 1 LINES)终止

方法3:

$query = "LOAD DATA LOCAL INFILE 'products.csv' INTO TABLE tmp_tbl LINES TERMINATED BY '\\r\\n' FIELDS TERMINATED BY ',' IGNORE 1 LINES";

DB::connection()->getpdo()->exec($query);

$query = "LOAD DATA LOCAL INFILE '".$file_path."' INTO TABLE tmp_tbl LINES TERMINATED BY '\\n' FIELDS TERMINATED BY ',' IGNORE 1 LINES";

DB::connection()->getpdo()->exec($query);

出现以下错误

  

SQLSTATE [42000]:语法错误或访问冲突:1064您有   SQL语法错误;查看与您的手册相对应的手册   MariaDB服务器版本,用于在'FIELDS附近使用正确的语法   终止','IGNORE 1 LINES'在第1行

方法4

$query = "LOAD DATA LOCAL INFILE '".$file_path."' INTO TABLE tmp_tbl";

DB::connection()->getpdo()->exec($query);

出现以下错误

  

PDO :: exec():MySQL服务器已经消失

方法5

$query = "LOAD DATA LOCAL INFILE '".$file_path."' INTO TABLE tmp_tbl";
DB::select($query);

出现以下错误

  

SQLSTATE [HY000]:常规错误:2014无法执行查询   其他未缓冲的查询处于活动状态。考虑使用   PDOStatement对象::使用fetchall()。或者,如果您的代码只是永远   要对mysql运行,您可以通过设置启用查询缓冲   PDO :: MYSQL_ATTR_USE_BUFFERED_QUERY属性。 (SQL:LOAD DATA   LOCAL INFILE'products.csv'INTO TABLE tmp_tbl)

我应该继续使用哪种方法以及为什么我会收到所有这些错误?我希望在更短的时间内处理所有记录而不会出现任何错误。

1 个答案:

答案 0 :(得分:0)

尝试将此DB::connection()->disableQueryLog();添加到脚本的顶部 - 您的内存消耗可能来自将查询存储在内存中。