Ответ вслух Middle EF Core спрашивают часто обновлено

Как найти и исправить N+1 в EF Core

Вопрос

Как вы находите и исправляете проблему N+1 в приложении на EF Core?

Попробуйте сами

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

Показать ответ и разбор

Коротко

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

Что должно прозвучать в ответе

  • Признаки: число запросов растёт с размером данных, много одинаковых SELECT

  • Диагностика: логирование SQL, MiniProfiler, APM, счётчик команд в тестах

  • Include и ThenInclude для нужных связей

  • Проекции через Select в DTO, подсчёты на стороне базы

  • AsSplitQuery против декартова взрыва

  • Отключённая ленивая загрузка как защита по умолчанию

Что могут спросить следом

  • Когда Include хуже проекции?
  • Как написать тест, который упадёт при появлении N+1?

Разбор

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

Нахожу через логирование SQL EF Core в Development, MiniProfiler или трейсинг в APM, где видно десятки одинаковых SELECT. Можно поставить в интеграционный тест перехватчик команд и проверять, что эндпоинт делает фиксированное число запросов.

Исправляю по ситуации. Если нужны сущности целиком, Include и ThenInclude, а для нескольких коллекций AsSplitQuery, чтобы не получить декартов взрыв. Для чтения чаще всего лучше проекция: Select в DTO только с нужными полями, а Count и Sum считаются в SQL. Ленивую загрузку держу выключенной: она удобна, но прячет запросы.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.