
Pendahuluan
Bayangin lagi ngerjain fitur dashboard analitik yang kompleks, tapi malah kena masalah performa gara-gara query N+1 yang nggak ada habisnya. Sering banget saya nemuin developer yang ngerasa mentok saat butuh data agregat yang relasinya ribet, lalu akhirnya malah nulis raw SQL panjang lebar di tengah model. Padahal, Eloquent punya cara elegan lewat subquery yang bikin query kamu lebih bersih dan performanya tetap terjaga di level database.
Tips & Best Practices
Di banyak project, biasanya saya mulai dari bikin 'Query Scope' buat logic yang bakal sering dipakai, biar nggak nulis ulang subquery di banyak controller. Kedua, manfaatin method selectSub kalau kamu cuma butuh satu kolom tambahan dari tabel lain tanpa harus eager loading seluruh model yang bikin boros memory. Terakhir, selalu perhatiin penggunaan index di kolom yang bakal di-join atau dibandingin di dalam subquery, karena percuma query-nya rapi kalau database-nya tetap harus scanning seluruh tabel pas proses eksekusi.
Contoh Kode
Misalnya kita mau ngitung total transaksi terakhir tiap user tanpa harus looping di PHP:
$users = User::addSelect(['last_transaction_date' => Transaction::select('created_at')
->whereColumn('user_id', 'users.id')
->latest()
->limit(1)
])->get();Cara ini jauh lebih enteng daripada kamu nge-load semua relasi transaksi terus difilter pakai collection PHP.
Variasi Implementasi
Ada dua pendekatan umum yang sering saya pakai. Pertama, pakai addSelect untuk nambahin satu kolom tambahan hasil agregat langsung dari query utama. Kedua, pakai whereIn atau whereExists dengan subquery kalau kamu mau memfilter data utama berdasarkan hasil kalkulasi tabel lain. Kalau datanya nggak terlalu besar, whereIn seringkali lebih enak dibaca, tapi buat dataset jutaan row, whereExists biasanya menang telak di sisi performa karena database bakal berhenti ngecek begitu ketemu match pertama.
Kesalahan Umum
- Lupa nambahin
whereColumndi dalam subquery yang akhirnya malah nge-fetch semua data dari tabel lain. - Terlalu nafsu pake subquery buat hal yang sebenernya bisa diselesain pakai
withCountbawaan Eloquent. - Mengabaikan penggunaan indeks di foreign key yang dipake di dalam
whereColumn. - Nulis subquery yang terlalu kompleks di dalam
orderBy, padahal database punya limitasi performa buat sorting hasil kalkulasi. - Asumsi kalau subquery selalu lebih cepet dari eager loading, padahal kalau datanya dikit, eager loading justru seringkali lebih efisien.
Ringkasan
Jadi, intinya subquery itu ibarat bumbu dapur; kalau dipake pas, masakan—eh, maksud saya query—kamu bakal berasa enak dan nggak berat di server. Jangan takut buat bereksperimen dengan toSql() buat ngecek hasil akhir query kamu sebelum di-running. Semakin sering kamu biasain pake cara ini, code kamu bakal lebih terlihat pro dan yang paling penting, performa app-nya jadi jauh lebih 'kenceng' tanpa harus ribet optimasi manual tiap hari.
Komentar
Posting Komentar