@barder

Как ускорить импорт CSV файла с 300к записей?

Привет всем.
В общем такая ситуация, есть файл CSV с 300к строк.
у меня виртуальный хостинг с ограничением по времени 300сек.

Читаю файл и обнавляю цену так:
//если файл читается...
if (($handle = fopen("price.csv", "r")) !== FALSE) {
        //обрабатываем построчно...
	while (($data = fgetcsv($handle, 4000, ";")) !== FALSE) {
                //обходим инфоблоки товаров по артикулу....
		$arFields = "";
		$arSelect = Array("ID", "NAME", "DATE_ACTIVE_FROM");
		$arFilter = Array("IBLOCK_ID"=>5, "PROPERTY_CML2_ARTICLE" => $data[4]);
		$res = CIBlockElement::GetList(Array(), $arFilter, false, Array("nPageSize"=>2), $arSelect);
		while($ob = $res->GetNextElement())
		{
			$arFields = $ob->GetFields();

		}

		if ($arFields) {
			//если найден элемент обнавляем цену
                        CPrice::SetBasePrice($arFields['ID'], (int)$data[12], "RUB", 0);
			
		}else{
                        //если НЕ найден элемент выводим информацию по нему
			?><pre><? print_r($data)?></pre><hr><?	
		}
	}
	echo $row;
	fclose($handle);
}
:

Проблема в том, что когда 5к строк, он отрабатывает, долго но отрабатывает, уходит меньше 300сек,
но в файле 300к позиций, это в 60 раз больше и времени на обработку нужно больше.

Вот теперь вопрос: как например читать с определенной строки, или как нибудь например я бы на кроне запускал бы каждые 10 минут читая по 1000 строк и удаляя их после чтения..., или есть может какой нибудь другой способ?

Пытался на VPS перейти, но VPS за 400р в мес, оказался слабее виртуального за 300р
  • Вопрос задан
  • 426 просмотров
Пригласить эксперта
Ответы на вопрос 2
FanatPHP
@FanatPHP
Чебуратор тега РНР
если файл простой, поля без кавычек и переводов строк, то читай fgets/explode
будет быстрее в 40 раз чем fgetcsv

плюс весь процесс заключить в транзакцию. тоже раз в 70 должно ускорить запись в базу

Но вообще конечно надо профилировать сначала. То есть смотреть, какая часть скрипта занимает сколько времени. чтобы не тыкать пальцем в небо.

Поэтому
1. Всё поставить на домашнем компе.
2. добавить перед циклом $time = time(); а после цикла - echo time() - $time;
3. Сначала закомментировать всю работу с базой - то есть оставить только чтение из файла, и посмотреть сколько оно занимает
4. Раскомментировать операторы чтения из БД, и вычесть из результата время на чтение файла - получим сколько времени занимает чтение
5. Раскомментировать остальное и замерить полное выполнение скрипта, с записью в БД.

С этими цифрами уже идти сюда.
И задавать осмысленный вопрос, "как мне ускорить такую-то операцию", а не "как мне прикрутить кривые костыли к моему кривому коду"
Ответ написан
$res = CIBlockElement::GetList(Array(), $arFilter, false, Array("nPageSize"=>2), $arSelect);

Вынесите это из цикла и обновляйте только те цены которые изменились и будет вам счастье.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы