Добро пожаловать на сайт <БагБД>, где вы можете задавать вопросы о программировании и разработке на Битрикс и Битрикс24, и получать быстрые и квалифицированные ответы от профессионалов!

Импорт из csv, как оптимизировать?

00 голосов
10
Задача: реализовать загрузку на сайт в каталог данных из csv файла + прикрепление картинок в публичной части, то есть для клиентов, которым не дан доступ в админку.

На данный момент сама по себе задача решена:
1) Файлы csv + картинки загружаются в 1 zip архиве
2) Архив распаковывается
3) Сначала обрабатываются построчно данные из csv файлов
4) Наконец подгружаются кратинки к элементам
То есть все работает.

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

Собственно вопрос: кто какие способы оптимизации предложит?

На данный момент используется:
1) Для добавления нового элемента ($Element содержит сразу и PROPERTY_VALUES):
Код
$el = new CIBlockElement;
$ID = $el->Add($Element);
2) Для обновления элемента:
Сначала для обновления свойств
Код
foreach($ElementProps as $PropCode=>$Value){
  CIBlockElement::SetPropertyValues($ElementID, $IBlock["ID"], $Value, $PropCode);
}
этот код вызванный для 9 элементов (по 4-5 свойств у каждого) генерирует ~136 запросов.
Затем для обновления самого элемента (и поискового индекса)
Код
$el = new CIBlockElement;
$el->Update($ElementID, $Element);
этот код вызванный для 9 элементов ($Element содержит только NAME, ACTIVE, DATE_ACTIVE_TO) генерирует ~535 запросов (! вообще ужас). На сколько я понял, в основном запросы тратятся на обновление поискового индекса... Так как, если его не обновлять (bUpdateSearch=true), количество запросов падает сразу да нескольких штук. Но ведь обновить его нужно, если элемент изменен.
3) Для подгрузки картинок (отдельно для каждого элемента):
Код
CIBlockElement::SetPropertyValues($ElementID, $IBlock["ID"], $arPicts, "IMAGE_MAIN");
этот код вызванный 5 раз (5 элементов) для загрузки 9 картинок (по 2-3 картинки у некоторых) генерирует ~99 запросов.
Итого около 800 запросов для обновления каких-то 9 элементов! А что будет, если подгрузить понадобится 200, 500 позиций?

Важно: используются инфоблоки+, т.е. хранение в отдельных таблицах.
спросил 12 Фев, 13 от Yoghurt (200 баллов)

10 Ответы

00 голосов
Для начала - пошаговый импорт
ответил 12 Фев, 13 от H9kA (480 баллов)
00 голосов
Цитата
Кирилл Попов пишет:
Для начала - пошаговый импорт
Это ясно - само собой разумеется.
Но вопрос я ставил не "как сделать, чтобы работало", а именно "как оптимизировать" - это самое главное, как сократить количество запросов.
ответил 09 Март, 13 от Yoghurt (200 баллов)
00 голосов
Добрый день.

У меня такой же вопрос как оптимизировать?
Я добавляю 100000 записей из csv файла с помощью функции добавления элемента. За секунду у меня проходит лишь 100 записей. Для проверки сделал то же самое, но через mysql_query() - 10000 записей в секунду.
Получается, чтобы добавить в базу, мне нужно ждать 16 минут. Я их буду добавлять каждый день, в дальнейшем у меня будет и 1 000 000 записей и больше.

Как можно добиться более скоростного добавления?
ответил 03 Апр, 13 от MadBird (180 баллов)
00 голосов
Помимо этой темы обратился в поддержку продукта, и ответа не последовало.

Поэтому отвечу сам.

1. Добавление ускоряется в 3-4 раза если удалить модуль поиска. Затем добавляю элементы $el->Add($Element) с bUpdateSearch = false. Минусы: - теряем модуль поиска, скорость добавления все равно не устраивает. Сойдет, если добавлять по 50-100 элементов за цикл.

2. Если элементов больше 50000 лучше вообще не использовать добавление битрикса. Выход из ситуации - свои таблицы + mysql_query или чтение из файлов. Это будет работать в десятки и сотни раз быстрее. Лично поверил на 1 000 000 записей.
ответил 29 Июль, 13 от MadBird (180 баллов)
00 голосов
Александр, я в общем к такому же выводу пришел. А не отвечают судя по всему из-за того, что ответа попросту нет...
Так что из решений и остается только:
1) Обязательное использование пошаговости
2) Добавление с отключенным поиском (bUpdateSearch = false) и затем уже переиндексация
3) Всякие самопальные оптимизации, вроде проверок на измененность, чтобы не обновлять то, что не изменилось
Так пока и делаю... В итоге на загрузку уходит до нескольких минут. А что делать?
ответил 01 Ноя, 13 от Yoghurt (200 баллов)
00 голосов
Как насчет использования стандартного скрипта импорта. Вроде у него со скоростью проблем нет. Не реализовывал, но, думаю, из публички его можно дернуть.
ответил 06 Фев, 14 от Biks (460 баллов)
00 голосов
Иван, да надо будет попробовать. Только он не совсем удовлетворяет. Либо придется переписывать, либо еще что. Функционал-то у него другой. Разве что подсмотреть, как в нем импорт реализован, и использовать оттуда функции в своем скрипте. Хотя я сомневаюсь, что там будет что-то относительно новое. Ну в общем глянем, когда время будет.
ответил 27 Май, 14 от Yoghurt (200 баллов)
00 голосов
Отпишитесь потом, интересно :)
ответил 24 Сен, 14 от Biks (460 баллов)
00 голосов
о. сейчас стоит похожая задача, практически идентичная =)
пока тоже отталкивался от $el->Add($Element). Элементов пока порядка 2000, даже на таких объемах оптимизация требуется. Была мысль вставлять записи в базу напрямую подготавливая обширные вставки, пока только мысль.

Иван подал хорошую идею посмотреть в сторону стандартного импорта, тоже сейчас буду его изучать.
ответил 28 Янв, 15 от rfgdjxd (160 баллов)
00 голосов
Иван, в файле импорта (bitrix\modules\iblock\admin\data_import.php) ничего нет, что могло бы ускорить процесс. Быстрее он не будет работать. Тут та же процедура Add(). У меня грузил в базу в 2,5 раза дольше моей обработки с той же процедурой (моя 4 минуты, скрипт - 9 минут)

Дмитрий Олареско, если будешь использовать стандартный импорт, перепроверь! соответствует ли количество элементов в базе. Случается, что скрипт может не добавить элементы, и при этом в отчете ошибки = 0.

NightCat, если найдешь метод - обязательно пиши, это поможет многим :)
ответил 11 Май, 15 от MadBird (180 баллов)

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

0 голосов
2 ответов
спросил 09 Фев, 15 от аноним
0 голосов
7 ответов
спросил 28 Июль, 13 от Asteria (1,840 баллов)
0 голосов
1 ответ
0 голосов
3 ответов
спросил 06 Март, 14 от Priory (100 баллов)