Описать проблему ↗

Скорость

Laravel N+1: страница делает много одинаковых запросов

Laravel делает много похожих запросов при открытии страницы. Разберём проблему N+1 на понятном примере и признаки, по которым её стоит проверять.

Редакция «починимсайт» · Обновлено · 3 мин. чтения

Что происходит и с чего начать

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

Что можно проверить самостоятельно

  1. Сравните экран с небольшим и обычным количеством записей. Запишите параметры фильтра, размер страницы и время открытия, не меняя одновременно другие условия просмотра.
  2. Уточните, какие связанные сведения показываются у каждой строки: клиент, категория, цена, остаток. Это помогает найти повторный доступ к данным в шаблоне или обработчике.
  3. Попросите измерить количество запросов вместе со временем. Один замер общей загрузки без связи с числом элементов не подтверждает именно эту причину задержки.

Как понять результаты проверки

В Laravel связанные данные можно получать заранее подходящим способом, но исправление должно учитывать объём и нужные поля. Загрузка всех возможных связей без разбора способна заменить множество запросов чрезмерным расходом памяти. Специалист выбирает необходимые данные, проверяет места обращения из шаблонов и сравнивает результат. Также важно не сломать ограничения доступа: заранее загруженный набор должен соответствовать полномочиям пользователя. Хорошая оптимизация сокращает лишнюю работу, сохраняя тот же смысл и состав показанных записей.

Что проверяет разработчик

Для этой части понадобятся доступ к настройкам, журналам ошибок или коду. Её можно передать специалисту вместе с результатами предыдущих шагов.

  1. Сравните страницу с небольшим и большим количеством элементов. Если число похожих запросов растёт вместе со списком, проверьте обращения к отношениям.
  2. Посмотрите шаблоны, сериализацию, аксессоры и вычисляемые поля. Дополнительный запрос может скрываться внутри удобного свойства модели.
  3. Проверьте выбранные колонки и ключи связей. Неполная выборка способна нарушить корректное сопоставление предварительно загруженных данных.

На что обратить внимание

Каждый отдельный запрос может быть быстрым, но суммарная задержка заметна из-за количества обращений. Один индекс не устраняет повторное получение одинаковых связей.

Как исправляют причину

Загружайте необходимые отношения заранее, а для подсчётов используйте подходящие агрегаты. Не загружайте все связи проекта без разбора: это увеличит память и объём данных.

Как убедиться, что проблема решена

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

Повторите замеры на исходном количестве элементов и проверьте поля каждой строки. Убедитесь, что пагинация, сортировка и права доступа работают как прежде. Полезно зафиксировать число запросов до и после, а также время и память. Исправление должно масштабироваться на обычный размер страницы, а не давать красивый результат только при одном объекте в тестовой базе.