SQL Anda Cepat, Namun API Anda Lambat
Query database Anda cepat. Caching Anda berfungsi. Background job Anda berjalan baik.
Namun, API Anda tetap lambat. Penggunaan CPU Anda tinggi.
Masalahnya bukan pada database Anda. Masalahnya ada pada lapisan Ruby.
Bottleneck sering terjadi setelah data keluar dari database dan masuk ke aplikasi Anda. Hal ini terjadi melalui tiga masalah utama:
- Serialisasi yang membengkak
- Alokasi objek yang berlebihan
- Komputasi yang berulang
Berikut cara memperbaikinya.
- Hentikan Serialisasi yang Membengkak
Banyak pengembang mengubah seluruh model menjadi JSON.
render json: @shipments
Jika sebuah pengiriman memiliki 40 kolom tetapi frontend Anda hanya membutuhkan 5, Anda membuang-buang siklus CPU. Anda juga berisiko membocorkan data pribadi seperti API key atau biaya.
Solusinya: kembalikan hanya field yang Anda butuhkan.
render json: @shipments.as_json(only: [:id, :tracking_no, :status])
Untuk kecepatan yang lebih baik lagi, gunakan pluck untuk mengambil data sebagai array. Ini sepenuhnya menghindari pembuatan objek ActiveRecord yang berat.
- Kurangi Alokasi Objek
Setiap objek yang dibuat Ruby memakan memori. Membuat ribuan objek selama satu request memaksa Garbage Collector (GC) bekerja lebih keras. Hal ini memperlambat seluruh sistem Anda.
Hindari membuat hash atau string baru di dalam loop.
Buruk:
@shipments.map do |s|
{ label: "#{s.tracking_no} - #{s.status.upcase}" }
end
Baik: Pindahkan data statis ke luar loop. Lakukan lebih banyak pekerjaan di database daripada di Ruby.
- Hindari Komputasi yang Berulang
Jika Anda memanggil metode yang sama berkali-kali dalam satu request, Anda membuang-buang waktu.
Contoh:
def total_weight
shipments.sum(&:weight)
end
Jika view, helper, dan serializer Anda semuanya memanggil ini, Anda menghitung jumlahnya tiga kali.
Solusinya: gunakan memoization.
def total_weight
@total_weight ||= shipments.sum(&:weight)
end
Ini memastikan perhitungan hanya terjadi satu kali per request.
Tabel Ringkasan:
- Serialisasi yang membengkak: Kembalikan hanya field yang dibutuhkan atau gunakan
pluck. - Alokasi tinggi: Buat lebih sedikit objek di dalam loop.
- Komputasi berulang: Gunakan memoization untuk menggunakan kembali hasil.
Optimasi database berarti meminta lebih sedikit data. Optimasi aplikasi berarti melakukan lebih sedikit pekerjaan tambahan setelah Anda mendapatkan datanya.
Sumber: https://dev.to/danewu/your-sql-is-fast-but-the-api-is-slow-its-the-ruby-layer-2fno
