Задать вопрос
iKatkovJS
@iKatkovJS
Symfony Developer

Почему замедляется работа скрипта?

Добрый день!
Работаю над алгоритмом XML парсера, который должен извлекать товары и добавлять в БД. Столкнулся с проблемой того, что чем больше докумен (больше товаров) тем медленее добавляется информация в БД. К примеру 2к товаров добавляются за 20 минут, а 16к за 20(!) часов. Подобная картина наблюдается даже если пересобрать xml документ в массив. В чем может быть проблема? Что мне нужно изучить, что бы решить просадку по скорости?

П.С Пример документа
  • Вопрос задан
  • 474 просмотра
Подписаться 1 Оценить Комментировать
Решения вопроса 2
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
оптимизировать работу с базой. Я на 99% уверен что:
- товары вставляются по одному
- перед каждой вставкой вы проверяете наличие категорий и прочего через базу, причем индексов в базе у вас нет или mysql (вы же mysql используете?) у вас настроена дефолтным образом и выходит много чтений с диска

Хотя даже при таком раскладе 20 часов для 16К элементов это как-то сильно долго...
Ответ написан
@jaxel
Каким образом парсите XML? На файлах большого объёма надо использовать способы, не загружающие файл в память. Например через XMLReader.

Как происходит добавление в базу? Доктриной? Если да, то надо разбивать добавление на небольшие пачки. Через каждые 100-200 $em->persist нужно делать $em->flush() и удалять сущности из списка управляемых $em->getUnitOfWork()->clear()

Ещё надо учесть, что в dev окружении каждый запрос профилируется, и при больших объёмах данных это даёт многократное замедление. Надо или делать запросы в prod окружении, или отключить профилирование:
$this->em->getConnection()->getConfiguration()->setSQLLogger(null);

        foreach ($this->em->getEventManager()->getListeners() as $event => $listeners) {
            foreach ($listeners as $listener) {
                $this->em->getEventManager()->removeEventListener($event, $listener);
            }
        }
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
jumper423
@jumper423
web-developer
Как мне кажется ты делаешь это с помощью отдельных INSERT-ов, если это так, то надо это оптимизировать. Для этого составляй разовые INSERT-ы с добавлением к примеру за раз тысячи записей.
Ответ написан
@mantyr
Пишу много Golang кода с удовольствием:)
Скорость вставки в базу можно проверить отдельно, посмотрев SHOW PROCESSLIST;

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

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

Гуглите на тему "поточный парсинг xml", с его помощью сможете парсить практически без ограничений и с минимальным потреблением ресурсов, в рамках возможного в PHP, конечно же.

Для сравнения кейс парсинга каталога книг с ozon.ru на Golang:
- 3.9 гигабайт файл xml
- 2.3 миллиона книг (у каждой книги название, авторы, описание, ссылка на обложку, перечень языков, стоимость книги, перечень категорий и отдельно список всех категорий к книгам)
- 10 минут поточного парсинга с сохранением в базу
- без предварительного сохранения на диск
- с автодокачкой при сетевых разрывах
Ответ написан
gbg
@gbg
Любые ответы на любые вопросы
Запустите atop и посмотрите, кто тормозит и что кушается - диск/сеть/CPU?
Ответ написан
Комментировать
Ваш ответ на вопрос

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

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