2014-08-27 2 views
1

Надеюсь, вы можете мне помочь. Я много искал, но, к сожалению, ничего не нашел. В чем проблема? У меня есть большие CSV-файлы с 1 столбцом, который содержит адреса электронной почты. В одном файле около 50000 строк. Я создаю панель администрирования, которая позволяет импортировать эти файлы на сервер, используя HTML-форму и PHP. Импорт CSV в базу данных MySQL через PHP прост, но мне нужно что-то еще - проверьте, все ли электронные письма существуют, а если да - пропустите. В чем проблема? В таблице содержится около миллиона + записей, проверка одного сообщения электронной почты длится +/- 3 секунды. 50000 записей умножается на 3 ... это займет мин. 44 часа! PHP скрипт перестает отвечать на запросы после того, как менее чем за 10 минут ... Так что это невозможно сделать это таким образом:Импорт больших CSV-файлов в базу данных MySQL с использованием PHP с проверкой дубликатов

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 массив.

Есть ли какой-нибудь другой и более быстрый способ сделать это?

+1

Опустите чек и просто используйте 'INSERT IGNORE'. Также может помочь правильный индекс в столбце электронной почты. – Sirko

+0

Действительно ли это 'WHERE subscriber_email LIKE: subscriber_email', имея ГДЕ И НРАВИТСЯ? Обычно я вижу пример, например 'WHERE subscriber_email = '$ email'. –

+0

@ Fred-ii- Я использую 'LIKE', потому что я не уверен, что' = 'нечувствителен к регистру. – Blacky

ответ

1

Ниже мое предложение:

1) Загрузите файл CSV в временной таблице. http://dev.mysql.com/doc/refman/5.1/en/load-data.html

2) Он будет загружать ваши данные csv очень быстро, может быть в считанные секунды. Теперь используйте запрос вставки и вставьте данные из временной таблицы в мастер-таблицу с проверкой двойного значения.

EG

1) Давайте предположим, что у вас есть данные в формате CSV нагрузки во временной таблице с именем "TempTable"

2) говорят, ваше имя основной таблицы "mailing_subscribers"

3) говорят, что вы не хотите дублировать запись для вставки.

ваш запрос будет как:

вставки в mailing_subscribers (subscriber_email, колу, colb ..) выберите subscriber_email, колой, colb .. из TempTable где не subscriber_email в (выберите subscriber_email из mailing_subscribers)

Пожалуйста, дайте мне знать, если вы столкнулись с какой-либо проблемой.

+0

Здравствуйте, @Ronak Shah хорошая идея, но если у csv есть дублирующаяся запись, и мы проверяем только на соблазнительные проблемы, так что может возникнуть проблема. я прав или не прав ?????? – Jalpesh

Смежные вопросы