Селект с пагинацией без селекта всех записей

Есть проект на laravel, в одном из методов по получению списка заявок я получаю общее кол-во заявок для пагинации и потом 20 из этого числа по смещению. На проде кол-во заявок уже около 150к, время выполнения не самое радужное, около 3 секунд У меня подозрения, что в момент фильтрации заявок Eloquent берет все записи, оттуда и долгое ожидания Если так, то есть ли способ не брать все заявки? Код таков:

$filter = app()->make(OrderFilter::class, ['params' =>  ArrayHelper::filter($data)]);

    $query = Order::filter($filter)
        ->whereHas('client')
        ->where('something', '=', 1)
        ->orderBy($sort, $order);
    $count = $query->count();
    $query = $query->limit($limit)->offset(($page - 1) * $limit);
    // something
    return [/*data from $query*/];

Я смотрел решения с помощью чанков, но это не подходит, ибо данные после всех манипуляций летят на фронт, чанки тут бесполезны будут


Ответы (1 шт):

Автор решения: Dmitry Vermutoff.com

Общие рекомендации

  1. Полагаю, что для параметра "something" у модели Order необходимо добавить индекс в таблицу orders, и затем использовать этот параметр первым в запросе.

  2. Долгим может быть именно запрос по по подсчету кол-ва заявок в таблице, поскольку выполняется обход всех требуемых строк.

  3. Для ускорения подобного мероприятия, можно попробовать переписать пагинацию по типу Cursor-пагинация - https://laravel.su/docs/8.x/pagination#cursor-paginaciia Для Cursor-пагинации используется несколько иной и более быстрый принцип выбора данных и формирования ссылок на страницы. Это подойдет в том случае, если ссылки на каждую страницу с заявками - не критичный функционал. То есть Cursor-пагинация даст ссылки только на следующую и предыдущую страницы.

Рекомендую использовать, как минимум, Debug-bar для Laravel, чтобы выяснить какой именно запрос выполняется долго, и затем оптимизировать.

→ Ссылка