Optimasi Performa Query Eloquent Laravel

Aplikasi Laravel yang lambat hampir selalu disebabkan oleh query database yang tidak efisien, bukan bahasa PHP-nya. Kabar baiknya, Eloquent menyediakan banyak alat untuk membuat qu...

Optimasi Performa Query Eloquent Laravel

Aplikasi Laravel yang lambat hampir selalu disebabkan oleh query database yang tidak efisien, bukan bahasa PHP-nya. Kabar baiknya, Eloquent menyediakan banyak alat untuk membuat query cepat — asalkan Anda tahu cara memakainya. Artikel ini membahas teknik optimasi query Eloquent yang paling berdampak, dari yang paling umum (N+1) hingga indexing dan caching, lengkap dengan kode nyata.

1. Atasi Masalah N+1 dengan Eager Loading

Ini adalah penyebab lambat nomor satu. N+1 terjadi ketika Anda mengambil sekumpulan data lalu mengakses relasinya di dalam loop:

$orders = Order::all();
foreach ($orders as $order) {
    echo $order->customer->name;   // 1 query TAMBAHAN tiap iterasi
}

Untuk 500 order, itu berarti 501 query. Gunakan with() untuk memuat relasi sekaligus:

$orders = Order::with('customer')->get();   // hanya 2 query

Anda juga bisa memuat relasi bersarang dan membatasi kolomnya:

$orders = Order::with([
    'customer:id,name',
    'items.product:id,name,price',
])->get();

Agar N+1 tidak lolos ke produksi, aktifkan pencegahan otomatis di AppServiceProvider:

use Illuminate\Database\Eloquent\Model;

public function boot(): void
{
    Model::preventLazyLoading(! app()->isProduction());
}

2. Ambil Hanya Kolom yang Dibutuhkan dengan select()

Secara default Eloquent menjalankan SELECT *. Jika tabel punya kolom berat seperti content atau metadata, Anda memboroskan memori dan bandwidth. Ambil kolom seperlunya:

$users = User::select('id', 'name', 'email')->get();

Jika hanya butuh satu kolom sebagai array, gunakan pluck() yang jauh lebih hemat:

$emails = User::where('active', true)->pluck('email');

3. Proses Data Besar dengan chunk() dan lazy()

Memuat 100.000 baris dengan get() bisa membuat aplikasi kehabisan memori. Untuk memproses data besar, ambil per potongan:

User::chunk(500, function ($users) {
    foreach ($users as $user) {
        // proses tiap user
    }
});

Alternatif yang lebih modern adalah lazy(), yang mengembalikan LazyCollection sehingga Anda tetap bisa memakai foreach biasa tanpa membebani memori:

foreach (User::lazy() as $user) {
    // hanya sebagian kecil baris di memori setiap saat
}

Untuk update massal, jika Anda mengubah kolom yang dipakai sebagai syarat, gunakan chunkById() agar tidak melewati baris.

4. Tambahkan Index Database

Index adalah cara paling ampuh mempercepat query WHERE, ORDER BY, dan JOIN. Kolom yang sering difilter (misalnya user_id, status, atau email) sebaiknya diberi index lewat migration:

Schema::table('orders', function (Blueprint $table) {
    $table->index('status');
    $table->index(['user_id', 'created_at']); // composite index
});

Foreign key sebaiknya selalu ter-index. Tanpa index, database harus memindai seluruh tabel (full table scan) untuk setiap query — sangat lambat saat data membesar.

5. Cache Hasil Query yang Jarang Berubah

Data seperti daftar kategori atau pengaturan situs jarang berubah tetapi sering diambil. Simpan hasilnya di cache agar tidak menembak database berulang kali:

use Illuminate\Support\Facades\Cache;

$categories = Cache::remember('categories', 3600, function () {
    return Category::orderBy('name')->get();
});

remember() mengembalikan data dari cache jika ada; jika tidak, ia menjalankan query, menyimpannya selama 3600 detik, lalu mengembalikannya. Jangan lupa hapus cache saat data diperbarui dengan Cache::forget('categories').

6. Temukan Query yang Lambat

Anda tidak bisa mengoptimasi apa yang tidak Anda ukur. Cara cepat memantau semua query adalah dengan DB::listen di AppServiceProvider:

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

DB::listen(function ($query) {
    if ($query->time > 100) {   // lebih dari 100 ms
        Log::warning('Query lambat', [
            'sql'  => $query->sql,
            'time' => $query->time,
        ]);
    }
});

Untuk pengembangan lokal, pasang Laravel Debugbar yang menampilkan jumlah query, durasi, dan duplikat langsung di browser:

composer require barryvdh/laravel-debugbar --dev

Debugbar akan langsung menyorot masalah N+1 karena Anda melihat query yang sama diulang berkali-kali.

7. Hitung dengan Benar

Untuk menghitung jumlah baris, jangan pernah memakai count(User::all()) yang memuat semua data ke memori. Gunakan agregat database:

$total = Order::where('status', 'paid')->count();

Untuk mengecek keberadaan data, exists() lebih cepat daripada count() > 0:

if (Order::where('user_id', $id)->exists()) {
    // ...
}

8. Pindahkan Perhitungan Berat ke Database

Kesalahan umum lain adalah mengambil banyak baris ke PHP hanya untuk menjumlahkan atau merata-ratakan nilainya. Serahkan pekerjaan itu ke database yang jauh lebih efisien untuk agregasi:

// Kurang efisien: memuat semua baris ke memori
$total = Order::where('status', 'paid')->get()->sum('amount');

// Efisien: database yang menghitung
$total = Order::where('status', 'paid')->sum('amount');

Hal yang sama berlaku untuk avg(), max(), dan min(). Untuk statistik yang mengelompokkan data, gunakan groupBy() di level query agar hanya hasil ringkasnya yang dikirim ke PHP. Ini bisa mengubah query yang memuat ribuan baris menjadi satu baris hasil saja.

Jika Anda menghitung jumlah relasi, hindari memuat seluruh relasi hanya untuk menghitungnya. Gunakan withCount():

$posts = Post::withCount('comments')->get();
// akses via $post->comments_count tanpa memuat komentarnya

Kesimpulan

Optimasi query Eloquent bukan sihir — ini tentang mengukur lalu memperbaiki. Prioritas Anda: hilangkan N+1 dengan eager loading, ambil hanya kolom yang perlu, index kolom yang sering difilter, proses data besar dengan chunk/lazy, cache data yang jarang berubah, dan serahkan agregasi ke database. Dengan Debugbar atau DB::listen sebagai mata Anda, aplikasi Laravel yang tadinya berat bisa menjadi ringan dan responsif. Terapkan satu per satu, ukur dampaknya, dan Anda akan melihat waktu respons turun drastis.

Tools untuk Memantau Query

Optimasi yang baik dimulai dari pengukuran, bukan tebakan. Manfaatkan alat pemantau seperti Laravel Debugbar atau Telescope untuk melihat jumlah kueri yang dijalankan tiap halaman, durasi eksekusinya, dan mendeteksi masalah N plus satu. Aktifkan query log saat pengembangan untuk menelusuri kueri yang lambat, lalu gunakan penjelasan rencana eksekusi database untuk memahami mengapa sebuah kueri lambat. Dengan data nyata di tangan, Anda dapat menentukan indeks yang tepat, memilih eager loading yang sesuai, dan menghindari optimasi prematur pada bagian yang sebenarnya tidak menjadi hambatan. Pemantauan rutin juga membantu menangkap regresi performa sejak dini sebelum berdampak ke pengguna. Ingat, kueri tercepat adalah kueri yang tidak perlu dijalankan, jadi pertimbangkan pula caching untuk data yang jarang berubah.

Yudhi
Ditulis oleh
Yudhi
Founder & Lead Developer, GudangCode

Yudhi adalah founder GudangCode dan developer Laravel dengan pengalaman membangun puluhan sistem informasi bisnis siap pakai — mulai dari POS, HRIS, hingga aplikasi manajemen. Ia menulis panduan dan artikel di GudangCode untuk membantu developer Indonesia menjalankan, memahami, dan men-deploy source code Laravel dengan benar.

Laravel PHP MySQL Sistem Informasi Bisnis
Lihat semua artikel Yudhi
Mau source code & aplikasi lengkapnya?

Daftar gratis untuk mengunduh aplikasi bisnis, sistem informasi, dan source code Laravel siap pakai.

Daftar Gratis & Download
Laravel Eloquent Performa Optimasi Database
📚 Free Learning Hub

Learn Coding for Free at DhieCoderWeb

Explore Laravel, PHP, JavaScript tutorials, source code, web development guides, and practical programming tips.

DhieCoderWeb
100+
Tutorials
Free
Learning
SEO
Tips
Visit Dhiecoderweb.com →

Dapatkan Akses Penuh Sekarang!

Bergabunglah menjadi member kami dan dapatkan akses eksklusif ke seluruh fitur unggulan aplikasi ini. Proses cepat, mudah, dan langsung bisa Anda gunakan.

Daftar Members Sekarang
Tim Support
Online
Isi data dulu untuk mulai chat:
Beri rating & testimoni sebelum menutup:
Live chat by gudangcode.com