Eager Loading: Solusi N+1 Query
Pahami masalah N+1 query yang bikin halaman lambat dan atasi dengan with() dan withCount().
Masalah N+1 query
Ini jebakan performa nomor satu di Laravel. Perhatikan kode ini:
@foreach ($posts as $post)
<p>{{ $post->judul }} oleh {{ $post->user->nama }}</p>
@endforeachKelihatannya 1 loop biasa, tapi di belakang layar terjadi 1 query untuk ambil semua post + N query untuk ambil user tiap post. Kalau ada 100 post, total 101 query. Di development tidak terasa, di production dengan data besar halamannya jadi lambat.
Solusi: with()
Beri tahu Laravel di awal relasi apa saja yang dibutuhkan, supaya diambil dalam 1-2 query saja:
// app/Http/Controllers/PostController.php
public function index()
{
// 2 query total, tidak peduli ada 10 atau 1000 post
$posts = Post::with('user')->latest()->paginate(15);
return view('posts.index', compact('posts'));
}Bisa juga nested dan multiple:
$posts = Post::with(['user', 'komentar.user', 'tags'])->get();Lazy eager loading
Kalau model sudah terlanjur diambil tanpa with(), load relasinya belakangan:
$posts = Post::all();
// Satu query tambahan untuk semua user, bukan N query
$posts->load('user');
$posts->loadMissing('tags'); // hanya yang belum di-loadwithCount: hitung tanpa ambil data
Butuh jumlah komentar tiap post tanpa me-load semua komentar? Pakai withCount():
$posts = Post::withCount(['komentar', 'komentar as komentar_published_count' => function ($q) {
$q->where('status', 'published');
}])->get();
foreach ($posts as $post) {
echo $post->komentar_count; // kolom virtual otomatis
}Catatan teknis: Cara termudah mendeteksi N+1 adalah menyalakan query log saat development:
DB::enableQueryLog()laludd(DB::getQueryLog()). Atau install Laravel Debugbar yang menampilkan jumlah query tiap halaman. Kalau satu halaman menjalankan ratusan query, hampir pasti ada N+1 yang belum di-eager-load.