Выбор ответа Junior Eloquent, N+1 и миграции спрашивают часто обновлено

N+1 в Eloquent

Вопрос

Сколько SQL-запросов выполнит код, если постов 50?

$posts = Post::all();
foreach ($posts as $post) {
    echo $post->author->name;
}

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

Выберите вариант, и откроется разбор.

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

Коротко

Правильный ответ: 51: один за посты и по одному на автора. Обращение к $post-author лениво загружает связь отдельным запросом для каждого поста: 1 + 50.

Варианты ответа

  1. 1: Eloquent сам объединит всё в один JOIN
  2. 2: посты и все авторы через IN (...)
  3. 50: по запросу на каждого автора поста
  4. 51: один за посты и по одному на автораправильный ответ

Разбор

Обращение к $post->author лениво загружает связь отдельным запросом для каждого поста: 1 + 50. Это проблема N+1. Решение: жадная загрузка Post::with("author")->get(), тогда запросов два: посты и все нужные авторы через WHERE id IN (...). В Laravel можно включить Model::preventLazyLoading() в разработке, и ленивая загрузка будет бросать исключение.

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

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