У меня есть файл CSV, который имеет 3,5 миллиона кодов в нем.
Я должен указать, что это только КОГДА-ЛИБО будет этим однажды.
csv похож
age9tlg,
rigfh34,
...
Вот мой код:
ini_set('max_execution_time', 600);
ini_set("memory_limit", "512M");
$file_handle = fopen("Weekly.csv", "r");
while (!feof($file_handle)) {
$line_of_text = fgetcsv($file_handle);
if (is_array($line_of_text))
foreach ($line_of_text as $col) {
if (!empty($col)) {
mysql_query("insert into `action_6_weekly` Values('$col', '')") or die(mysql_error());
}
} else {
if (!empty($line_of_text)) {
mysql_query("insert into `action_6_weekly` Values('$line_of_text', '')") or die(mysql_error());
}
}
}
fclose($file_handle);
Этот код собирается умереть часть путь через на мне? Будет моя память и макс. время выполнения быть достаточно высокой?
NB: Этот код будет выполнен на моем localhost и базе данных, находится на том же ПК, таким образом, задержка не является проблемой.
вот другая возможная реализация. Этот делает это, оптом вставляет 2 000 записей
$file_handle = fopen("Weekly.csv", "r");
$i = 0;
$vals = array();
while (!feof($file_handle)) {
$line_of_text = fgetcsv($file_handle);
if (is_array($line_of_text))
foreach ($line_of_text as $col) {
if (!empty($col)) {
if ($i < 2000) {
$vals[] = "('$col', '')";
$i++;
} else {
$vals = implode(', ', $vals);
mysql_query("insert into `action_6_weekly` Values $vals") or die(mysql_error());
$vals = array();
$i = 0;
}
}
} else {
if (!empty($line_of_text)) {
if ($i < 2000) {
$vals[] = "('$line_of_text', '')";
$i++;
} else {
$vals = implode(', ', $vals);
mysql_query("insert into `action_6_weekly` Values $vals") or die(mysql_error());
$vals = array();
$i = 0;
}
}
}
}
fclose($file_handle);
если я должен был использовать этот метод, каково самое высокое значение, которое я мог установить его для вставки сразу?
таким образом я нашел, что могу использовать
LOAD DATA LOCAL INFILE 'C:\\xampp\\htdocs\\weekly.csv' INTO TABLE `action_6_weekly` FIELDS TERMINATED BY ';' ENCLOSED BY '"' ESCAPED BY '\\' LINES TERMINATED BY ','(`code`)
но проблема теперь - то, что, я был неправ относительно формата CSV, это - на самом деле 4 кода и затем разрыв строки, таким образом, fhroflg, qporlfg, vcalpfx, rplfigc,
vapworf, flofigx, apqoeei, clxosrc,
...
таким образом, я должен смочь указать две СТРОКИ, ЗАВЕРШЕННЫЕ
этот вопрос был расширен к Здесь.
При установке его, чтобы сделать объем вставляет 20k строк, с помощью
while (!feof($file_handle)) {
$val[] = fgetcsv($file_handle);
$i++;
if($i == 20000) {
//do insert
//set $i = 0;
//$val = array();
}
}
//do insert(for last few rows that dont reach 20k
но это умирает в этой точке, потому что по некоторым причинам $val содержит 75k строки и идею почему?
обратите внимание, что вышеупомянутый код упрощен.
Я сомневаюсь, что это будет популярный ответ, но я бы попросил ваше приложение php запускать mysqlimport в файле csv. Конечно, он оптимизирован намного больше, чем вы делаете в php.
этот код умрет частично через меня? будет моя память и макс время выполнения достаточно велико?
Почему бы вам не попытаться выяснить?
Вы можете настроить ограничения как для памяти ( memory_limit
), так и для времени выполнения ( max_execution_time
) , так что, если вам действительно нужно это использовать, это не должно быть проблемой.
Обратите внимание, что MySQL поддерживает отложенную вставку и вставку нескольких строк:
INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);
Вы должны накапливать значения и вставлять их в базу данных сразу в конце или партиями каждые x записей. Выполнение одного запроса для каждой строки означает 3,5 миллиона SQL-запросов, каждый из которых несет определенные накладные расходы.
Кроме того, вы должны запустить это в командной строке, где вам не придется беспокоиться об ограничениях времени выполнения.
Настоящий ответ - это ответ evilclown: импорт в MySQL из CSV - уже решенная проблема.
Я сделал это при импорте большой базы данных Access в Postgres с помощью perl и уменьшил время вставки до 30 секунд. Я бы использовал инструмент импорта, но я хотел, чтобы Perl обеспечивал соблюдение некоторых правил при вставке.
Я надеюсь, что нет веб-клиента, ожидающего ответа по этому поводу. Помимо вызова уже упомянутой утилиты импорта, я бы начал это как задание и почти сразу же отправил бы отзыв клиенту. Сделайте так, чтобы цикл вставки обновлялся на процентное завершение где-нибудь, чтобы конечный пользователь мог проверить статус, если вам абсолютно необходимо сделать это таким образом.
2 возможных способа.
1) Пакетный процесс, затем запланированное задание импортирует файл, одновременно обновляя статус. Таким образом, вы можете иметь страницу, которая постоянно проверяет статус и обновляется, если статус еще не достиг 100%. Пользователи будут иметь актуальную информацию о том, сколько всего было сделано. Но для этого вам нужен доступ к ОС, чтобы установить задачу по расписанию. И задача будет простаивать, когда нечего импортировать.
2) Пусть страница обработает 1000 строк (или любое N-ное количество строк... решайте сами), затем пошлет java-скрипт браузеру, чтобы он обновился с новым параметром, чтобы сообщить скрипту, что нужно обработать следующие 1000 строк. Вы также можете отобразить статус для пользователя, пока это происходит. Единственная проблема заключается в том, что если страница каким-то образом не обновится, то импорт остановится.