Проблемы с запросами Laravel DB, вызванные циклом findOrFail в for - PullRequest
0 голосов
/ 20 февраля 2019

Мое приложение обрабатывает тысячи записей базы данных и позволяет пользователю экспортировать определенную часть списка результатов поиска.

Каждый Entry содержит определенные файлы, и пользователь хочет загрузить их в сжатый файл (например, почтовый индекс).Это работает нормально, но я, скорее всего, использую max timeout .Я попытался по причинам отладки просто настроить max_execution_time для PHP вообще и в моем сценарии php.Оба не пропустили ошибку.

В основном у меня есть два вопроса:

  1. Как правильно проанализировать проблему?(Связано ли это с максимальным временем выполнения)
  2. Как пропустить максимальное время ожидания выполнения?(Скорее всего, это так, потому что с меньшим количеством запросов это работает просто отлично)

Пример кода:

public function export(Requests\ExportRequest $request)
{
    $input = $request->all();

    foreach ($input['entries'] as $id) {
        $entry = Entry::findOrFail($id);
    }
}

РЕДАКТИРОВАТЬ:

Кстати, проблема была не в max_execution_time, даже при том, что она значительно сократила количество запросов SQL.Проблема была вызвана ограничением max_input_vars.Целевые записи были проверены в форме и отправлены в функцию export ().Каждый флажок имел name=entries[], из-за чего каждая запись имела отдельное входное значение.Вы можете прочитать больше об этой проблеме здесь: Есть ли ограничение на отмеченные флажки в форме PHP POST? (Рассмотрите также чтение этого конкретного ответа )

1 Ответ

0 голосов
/ 20 февраля 2019

Вы столкнулись с проблемой N + 1: вы выполняете отдельный запрос для каждой записи, которую хотите получить.Вы можете получить все записи одновременно, написав запрос, который делает это.Я точно не знаю, что происходит после кода, который вы опубликовали, так как код на самом деле ничего не делает.Но выполнение 1000 отдельных запросов на несколько порядков медленнее, чем выполнение 1 большого запроса.

public function export(Requests\ExportRequest $request)
{
    $input = $request->all();

    $allEntries = Entry::whereIn('entry_id', $input['entries'])->get();

    // All entries is a Collection with all the queried entries in it
}

Мое эмпирическое правило заключается в том, что всякий раз, когда в игру вступает max_execution_time, я принимал неверное архитектурное решение.Может быть, мое решение решает проблему, может быть, @ TheFallen's.Но нам нужно больше кода для анализа этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...