Как я могу улучшить производительность импорта больших данных в Symfony?

Мне нужно сделать импорт в db из большого файла csv, около 100 000 записей.

Для этого я попробовал dql и орм, но с двумя вариантами мне требуется около 9 часов, чтобы завершить процесс.

Я сделал ту же загрузку с Node.js, и она пошла намного быстрее, около 5 минут.

Так что я не знаю, есть ли какой-нибудь вариант.

Я пытался очищать и смывать каждые 20 строк файла, но это все равно медленно

Есть идеи, как улучшить эту производительность.

Спасибо.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Symfony Station Communiqué - 17 февраля 2023 г
Symfony Station Communiqué - 17 февраля 2023 г
Это коммюнике первоначально появилось на Symfony Station , вашем источнике передовых новостей Symfony, PHP и кибербезопасности.
Управление ответами api для исключений на Symfony с помощью KernelEvents
Управление ответами api для исключений на Symfony с помощью KernelEvents
Много раз при создании api нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
2
0
1 451
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В зависимости от того, как выглядит ваш импорт, вы можете полностью обойти Doctrine ORM и получить соединение от Entity Manager с работать с DBAL. Таким образом, вы можете просто получить массив из CSV, а затем вставить их.

$dbal= $this->entityManager->getConnection();
$handle = fopen('exported_data.csv', 'r');
while (($row = fgetcsv($handle)) !== false)) {
    if (null === $row) {
        // Deal with invalid csv data
    }
    // maybe map row names to column names
    $dbal->insert('table_name', $row);
}
fclose($handle);

Это уже должно немного улучшить ситуацию. Затем вы должны увидеть, имеет ли смысл транзакции и вставки небольшими партиями. К счастью, поскольку вам не нужно иметь дело с гидратацией объекта и единицей работы из ORM, вам не нужно чистить каждый раз.

Вы также можете посмотреть на Пакетные утилиты Doctrine от ocramius, одного из участников Doctrine, для вашей задачи.

Если после этого у вас все еще есть проблемы с производительностью, вам следует начать профилирование вашего приложения с помощью таких инструментов, как черный огонь или xhprof. Это покажет вам, какая часть вашего кода на самом деле вызывает проблему с производительностью. Это может быть дисковый ввод-вывод, и даже fgetcsv() иногда может быть медленным из-за способа чтения фрагментов данных, но это влияет на производительность на таком низком уровне, что я бы не стал с ним беспокоиться, если только профилировщик не скажет мне тоже.

Только с dbal я перешел с 2 вставок в секунду до 40 вставок в секунду. Можно было бы достичь 100 или 500 вставок в секунду при хорошем подключении к Интернету?

Tlaloc-ES 17.10.2018 11:25

Может быть. Как я уже сказал, было бы лучше провести профилирование. Blackfire легко настроить, и они предлагают пробный период, в течение которого вы можете получить полный отчет в течение 14 или 30 дней, я не уверен. Он скажет вам, где ваши узкие места, например если проблема в сети или может быть какая-то часть вашего php-кода. Отказ от ответственности: я работаю в SensioLabs, поэтому технически я связан с Blackfire. Но попробуйте бесплатную версию, это отличный инструмент для поиска проблем с производительностью. :)

dbrumann 17.10.2018 11:42

хорошо, я попробую пробную версию, отличный ответ и всем спасибо.

Tlaloc-ES 17.10.2018 11:45

Другие вопросы по теме