Первый вопрос, укажите, можно ли его прояснить. Я много раз использовал ответы StackOverflow, поэтому спасибо за помощь!
Веб-сайт, который я разрабатываю, должен импортировать множество записей из файла CSV. Преобразование данных и сохранение в данный момент работают, но поскольку в одном файле может быть несколько тысяч записей, импорт данных в БД может быть ОЧЕНЬ долгим.
Как лучше всего сохранить в БД большой массив записей (массив массивов, содержащих данные для каждой записи)?
Вот код, который я использую сейчас:
for ($i = 0; $i < count($participants); $i ++)
{
Participant::firstOrCreate( [ 'survey_id' => $participants[$i]['survey_id'],
'id_importe' => $participants[$i]['id_importe'] ],
array_merge( $participants[$i], ['token' => $savedInLime[$i]['token']] ) );
}
Я сохранил построение массива там, но важная часть: есть ли лучший способ, чем цикл в массиве и "firstOrCreating" каждой записи?
РЕДАКТИРОВАТЬ
Я протестировал эти методы с таймером на каждом для файла, содержащего около 3900 записей.
TL; DR: «create» только немного быстрее, чем «firstOrCreate» и «insert» намного медленнее из-за двойного цикла.
1 - Я использовал свой предыдущий код для firstOrCreate, и это заняло 216 секунд
2 - Я использовал этот код для «создания», он был немного быстрее (205 с), но не гарантирует, что запись не является копией.
for ($i = 0; $i < count($participants); $i ++)
{
Participant::create(
'id_importe' => $participants[$i]['id_importe'] ],
array_merge( $participants[$i], ['token' => $savedInLime[$i]['token']] ) );
}
3 - Я использовал этот код для вставки (возможно, это можно было бы сделать быстрее с помощью функции массива), и это заняло 460 секунд. Мне пришлось использовать array_chunk из-за предела заполнителя базы данных (я думаю, немного выше 60k).
$tmp = array();
for ($i = 0; $i < count($participants); $i ++){
$tmp[] = array_merge( $participants[$i], ['token' => $savedInLime[$i]['token']] );
}
$inserts = array_chunk($tmp, 2000);
foreach ($inserts as $insert){
Participant::insert($insert);
}
Попробуйте синхронизировать Laravel или прикрепить / отсоединить: //laravel.com/docs/5.6/eloquent-relationships#upda ting-many-to-many-re lationships
Да, @AdreAstrian, пользователи будут импортировать файлы, поэтому они могут ошибаться. Записи не существуют, поэтому, если я не ошибаюсь, это не создание отношения.






Попробуй это:
$participants = [
['participant_id' => 11, 'survey_id' => 1),
['participant_id' => 22, 'survey_id' => 2),
];
Participant::insert($participants);
Но это не коснется меток времени IIRC.
Это, безусловно, быстрее, но не будет проверять, есть ли уже предмет. Возможно, я решу, что это лучше, проведя тест по первому элементу, чтобы увидеть, существует ли он. Это вопрос времени, чтобы получить VS анти-двойная безопасность ... Обновлено: для этой таблицы не нужны временные метки.
Я протестировал несколько методов, но, похоже, вставка не работает быстрее, если вы не думаете, что мой метод "вставки" можно значительно улучшить?
Просто для тех, кто достаточно новичок, чтобы не знать лучше:
В итоге я сохранил технику loop + firstOrCreate, поскольку потеря времени по сравнению с выигрышем в надежности была незначительной.
И вы не уверены, есть ли конкретная запись в БД или нет, поэтому вам нужно проверить ее перед тем, как вводить. Это так?