Skip to content

N+1 Query problem pada Manajemen User #943

@Revanza1106

Description

@Revanza1106

Deskripsi Masalah

Terdapat beberapa masalah N+1 query di aplikasi yang dapat menyebabkan masalah performa, terutama saat menangani dataset dalam jumlah besar. Masalah ini sangat terlihat pada:

  1. Manajemen User (DataTables) - Panggilan API untuk mengambil data kabupaten dilakukan untuk setiap baris
  2. Model User - Relasi team di-query individual untuk setiap user
  3. Front-end listing artikel - Relasi category tidak di-eager load

Dampak

  • Performa menurun drastis dengan dataset besar (100+ user = 100+ query tambahan)
  • Beban bertambah pada API eksternal (database gabungan)
  • Waktu load halaman lebih lambat untuk manajemen user dan halaman front-end

Perilaku yang Diharapkan

  • Semua data relasi harus di-eager load untuk mencegah N+1 queries
  • Panggilan API eksternal harus diminimalkan dan di-cache dengan benar
  • Query database harus dioptimalkan untuk pengambilan data bulk

Perilaku Aktual (Masalah)

Masalah 1: UserController - N+1 pada API Kabupaten

Lokasi: app/Http/Controllers/UserController.php:42-54

Setiap baris di DataTable memicu panggilan API terpisah untuk mengambil data kabupaten:

->addColumn('nama_kabupaten', function ($row) {
    $kabupaten = (new ConfigApiService)->kabupaten([
        'filter[kode_kabupaten]' => $row->kode_kabupaten,
    ]);
    return optional($kabupaten->first())->nama_kabupaten ?? '-';
})

Hasil: 1 query + N panggilan API untuk data kabupaten

Masalah 2: Model User - N+1 pada Relasi Team

Lokasi: app/Models/User.php:142-145

Method adminlte_desc() meng-query team untuk setiap user:

public function adminlte_desc()
{
    return $this->team()->first()->name;
}

Masalah sama juga terjadi pada getTeamId() di baris 132-135.

Masalah 3: Front-end Articles - N+1 pada Category

Lokasi: app/Http/Controllers/Web/PageController.php:45

Artikel diambil tanpa eager loading category:

'articles' => Article::where('category_id', $category->id)->paginate(4),

Solusi yang Diusulkan

  1. Untuk UserController: Pre-fetch semua data kabupaten dan buat lookup map
  2. Untuk Model User: Cek apakah relasi sudah di-load sebelum melakukan query
  3. Untuk PageController: Tambahkan eager loading untuk relasi category

Konteks Tambahan

Masalah ini mempengaruhi:

  • Performa panel admin (halaman daftar user)
  • Performa front-end (listing artikel)
  • Beban API eksternal (database gabungan)

Jumlah query database sebelum perbaikan:

  • Daftar user (100 user): 1 query + 100 panggilan API = ~101 total request

Jumlah query database setelah perbaikan:

  • Daftar user (100 user): 1 query + 1 panggilan API = ~2 total request

Perbaikan performa: ~98% pengurangan query

Checklist

  • Identifikasi semua lokasi N+1 query
  • Implementasi perbaikan
  • Test perubahan

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions