【发布时间】:2015-05-25 02:24:54
【问题描述】:
晚上好,我有一个 400mb 的 csv 文件,我必须将它加载到 mysql 数据库中。 csv 文件是“不规则的”,因为它包含以下信息:
user|email|password\n
user|password|otherdata\n
我在 php-cli 中编写了一个脚本来逐行读取文件并获取我需要的信息:用户名和密码。 l '用户名永远是第一条记录。要知道'密码是什么我看字符串的长度。
我在五个小时前运行了脚本,但还没有完成数据库中所有数据的加载。
如何提高此脚本的性能?
<?php
$fileHandle = fopen("C:/Users/AT/Documents/Backup/forumusers.csv", "r");
$mysqlHandle = mysql_connect("localhost", "root", "");
mysql_select_db("testbackupboard");
while(!feof($fileHandle))
{
$fileRow = fgets($fileHandle);
$line2Record = explode("|", $fileRow);
foreach ($line2Record as $rowRecord)
{
if (strlen($rowRecord) == 40)
{
$datatoMysql[0] = $rowRecord; // password hash
}
}
$datatoMysql[1] = $line2Record[0]; // username
$execQuery = mysql_query("INSERT INTO forumusers (username, hash) VALUES ('".mysql_real_escape_string(utf8_encode($datatoMysql[1]))."', '".mysql_real_escape_string(utf8_encode($datatoMysql[0]))."')");
if($execQuery)
{
print"Record ".$rowRecord[1]." ".$rowRecord[0]." loaded into db\n";
}
else
{
die(mysql_error());
}
}
fclose($fileHandle);
?>
【问题讨论】:
-
规则 #1:如果可能,使用 MYSQL 的 LOAD DATA INFILE
-
规则 #2:如果使用 PHP,则使用 PHP 内置的 fgetcsv() 函数而不是 fgets() 和 explode()
-
规则 #3:如果使用 PHP,您不应该根据值的长度来寻找密码哈希,它应该是一个始终可识别的特定列......所以不要浪费精力将您的行减少到一个 2 条目数组,只需在 SQL 中使用 fgetcsv() 数组中的相关列
-
@Mark Baker:最好给出一个答案,而不是多个 cmets。在 AntonioT:有很多方法可以改善这一点。最快的方法之一是使用一个 INSERT 将多行插入到数据库中。您几乎可以通过一次插入的行数来加快速度。
标签: php mysql performance parsing csv