【发布时间】:2014-08-27 08:59:23
【问题描述】:
我希望你能帮助我。我搜索了很多,但不幸的是没有找到任何东西。有什么问题?我有 1 列的大 CSV 文件,其中包含电子邮件地址。单个文件大约有 50000 行。我正在创建管理面板,它允许使用 HTML 表单和 PHP 将这些文件导入服务器。通过 PHP 将 CSV 导入 MySQL 数据库很简单,但我需要更多的东西 - 检查每封电子邮件是否存在,如果存在 - 跳过它。有什么问题?表有大约百万+记录,检查一封电子邮件持续 +/- 3 秒。 50000 条记录乘以 3... 需要最少的时间。 44小时! PHP 脚本在不到 10 分钟后停止响应......所以不可能这样做:
function doesExist($email) {
$sql = "SELECT count(*) as counter FROM mailing_subscribers WHERE subscriber_email LIKE :subscriber_email";
$sth = $this->db->prepare($sql);
$sth->execute(array(':subscriber_email' => $email));
$row = $sth->fetch();
$counter = $row->counter;
if ($counter > 0) {
return true;
} else {
return false;
}
}
function importCSV($file,$group) {
$fp = fopen($file['tmp_name'], "r");
$importsCounter = 0;
while($csv_line = fgetcsv($fp)) {
for ($i = 0, $j = count($csv_line); $i < $j; $i++) {
if (!$this->doesExist($csv_line[$i])) {
$sql = "INSERT INTO mailing_subscribers(subscriber_email,subscriber_group) VALUES('".$csv_line[$i]."','".$group."')";
$sth = $this->db->prepare($sql);
$sth->execute();
$importsCounter++;
}
}
}
$_SESSION["feedback_positive"][] = FEEDBACK_FILE_IMPORT_SUCCESSFUL . " Utworzonych wpisów: " . $importsCounter;
}
$file 是一个 $_FILE 数组。
还有其他更快的方法吗?
【问题讨论】:
-
省略检查,直接使用
INSERT IGNORE。电子邮件列上的适当索引也会有所帮助。 -
这是有效的
WHERE subscriber_email LIKE :subscriber_email,有 WHERE 和 LIKE 吗?我通常以WHERE subscriber_email = '$email'为例。 -
@Fred-ii- 我使用
LIKE因为我不确定=是否不区分大小写。 -
@Sirko 我在某处看到了 INSERT IGNORE,但是......只需将
subscriber_email列设置为unique就足够了? -
@Blacky 加上
INSERT IGNORE应该够了,是的。您还应该使用批量插入,而不是每个条目一个 SQL 语句。