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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions