Столкнулся с проблемой при импорте в инфоблок из CSV-файла. На VPS nginx хватал таймаут и выдавал 404. Вроде сначала всё идёт хорошо: выполняется пошагово импорт, но на последнем шаге сервер задумывается и... В-общем, начал разбираться.
[spoiler]
Элементов в инфоблоке у меня было около 55 000. А в CSV-файле не так уж и много, около 18 000. К тому-же, импорт доходил до конца файла. Путем добавления некоторого отладочного вывода в файл импорта (/bitrix/modules/catalog/load_import/csv_new_run.php) выяснилось, что проблема в коде, который снимает активность с товаров, отсутствующих в прайсе.
Что здесь происходит? Выбираются элементы, которые не были затронуты текущим импортом и по очереди с каждого снимается активность. Но зачем делать N+1 запросов для деактивации N элементов, когда можно сделать один?
Мою проблему этот фикс решил, по этому дальше я копаться не стал. Но уверен, можно сделать импорт ещё более быстрым.
[spoiler]
Элементов в инфоблоке у меня было около 55 000. А в CSV-файле не так уж и много, около 18 000. К тому-же, импорт доходил до конца файла. Путем добавления некоторого отладочного вывода в файл импорта (/bitrix/modules/catalog/load_import/csv_new_run.php) выяснилось, что проблема в коде, который снимает активность с товаров, отсутствующих в прайсе.
$res = CIBlockElement::GetList( array(), array("IBLOCK_ID" => $IBLOCK_ID, "!TMP_ID" => $tmpid), ); while($arr = $res->Fetch()) { ... else // H { $el->Update($arr["ID"], Array("ACTIVE" => "N"), false, false); $killed_lines++; } } |
Что здесь происходит? Выбираются элементы, которые не были затронуты текущим импортом и по очереди с каждого снимается активность. Но зачем делать N+1 запросов для деактивации N элементов, когда можно сделать один?
$DB->query("UPDATE `b_iblock_element` SET `ACTIVE` = 'N' WHERE `TMP_ID` != '".$tmpid."'"); |
Мою проблему этот фикс решил, по этому дальше я копаться не стал. Но уверен, можно сделать импорт ещё более быстрым.