500k行81列のCSVファイルを読み込み、データベースに挿入しようとしています。 CSVサイズは160 MBです。私は3〜4時間ごとにそれを処理しなければならない。 3〜4時間ごとに、私はいくつかの新しいレコードといくつかの既存のCSVを持っていきます。そのために私は多くの方法に従ってきましたが、完璧に働くものはありませmysqlロードデータinfileを使用して大きなcsvファイルを処理する
方法1:すべてのレコードを読み取りますが、時間がかかりすぎます。 200kレコードを読み込み、タイムアウトするまでには1時間以上かかりました。解決策として
$file = fopen($path, 'r');
while (($line = fgetcsv($file)) !== FALSE) {
}
:私はこのエラーを回避するためにPHPの制限、excution時間とメモリの制限を増やすことができますが、私はそれが非常に遅いと感じます。
方法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]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'FIELDS TERMINATED BY ',' IGNORE 1 LINES' at line 1 (SQL: LOAD DATA LOCAL INFILE 'products.csv' INTO TABLE tmp_tbl LINES TERMINATED BY '\r\n' FIELDS TERMINATED BY ',' 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]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'FIELDS TERMINATED BY ',' IGNORE 1 LINES' at line 1
方法4
$query = "LOAD DATA LOCAL INFILE '".$file_path."' INTO TABLE tmp_tbl";
DB::connection()->getpdo()->exec($query);
ガット次のエラー
PDO::exec(): MySQL server has gone away
方法5
$query = "LOAD DATA LOCAL INFILE '".$file_path."' INTO TABLE tmp_tbl";
DB::select($query);
ガット次のエラー
SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute. (SQL: LOAD DATA LOCAL INFILE 'products.csv' INTO TABLE tmp_tbl)
どの方法を使用し続ける必要がありますか、なぜこれらのエラーがすべて発生するのですか?エラーのない短い時間ですべてのレコードを処理したい。
なぜ方法#1はあまりにも多くのメモリを取るべきですか?配列にループを張ってデータベースに挿入する前に、csvからすべてのレコードの配列を作成しようとしていますか? –
いいえ配列を使用していません。fgetcsvを使用して1行ずつアクセスし、データベースに挿入/更新しています。 – Jass
それはどんな方法でも高いメモリ使用量であってはなりません。速度は潜在的に問題ですが、メモリを増やす理由はありません –