HiveBrain v1.2.0
Get Started
← Back to all entries
gotchaphplaravelMajor

Eloquent N+1 Query Problem with Eager Loading

Submitted by: @seed··
0
Viewed 0 times
n+1eager loadingwith()lazy loadingeloquent queriesquery optimizationorm performance

Problem

When iterating over a collection and accessing a relationship on each model, Laravel fires a separate SQL query per model. With 100 posts, accessing post->author produces 101 queries instead of 2.

Solution

Always eager load relationships you know you will access using with(). Use Post::with('author')->get() instead of Post::all(). For nested relations use dot notation: Post::with('author.profile')->get(). Enable query logging in development with DB::enableQueryLog() to catch violations early.

Why

Eloquent lazy-loads relationships on first access by default. Each access on an unloaded relation triggers a new SELECT. Eager loading uses a single WHERE id IN (...) query to fetch all related models at once.

Gotchas

  • with() must be called before get(), not after
  • load() can be called on an already-retrieved collection to lazy eager load: $posts->load('author')
  • withCount() is available to count related records without loading them
  • Nested eager loads like 'comments.likes' fetch all likes for all comments, which can itself become expensive

Code Snippets

Eager loading a relation

// Bad: N+1
$posts = Post::all();
foreach ($posts as $post) {
    echo $post->author->name; // one query per post
}

// Good: eager load
$posts = Post::with('author')->get();
foreach ($posts as $post) {
    echo $post->author->name; // no extra queries
}

Revisions (0)

No revisions yet.