Pelajaran modul (4/4)
Masalah N+1
Dalam pengembangan backend, salah satu kesalahan paling umum yang menyebabkan penurunan kinerja API adalah masalah "N + 1 Kueri" yang terkenal.
Biasanya merayap tanpa diketahui oleh pengembang yang menggunakan abstraksi perpustakaan seperti "ORM" (Pemeta Relasional Objek: misalnya Prisma atau Sequelize) untuk berkomunikasi dengan database dari Node.js.
Anatomi Bencana
Bayangkan sebuah aplikasi ingin menampilkan seluruh daftar beranda e-niaga: Semua produk beserta rangkaian nama kategori yang dimiliki masing-masing produk. Dilihat dari sisi Node.js, seorang programmer yang tidak berpengalaman akan menulis loop berulang:
products = await db.query("SELECT * FROM products");(Satu operasi besar dan besar 1)- Pengembang mengulangi (
for..of) pada setiapproductdalam larik 100 yang ditemukan - Pada setiap langkah, di Node.js mereka menunggu sub-kueri berulang
categoryName = await db.query("SELECT name FROM categories WHERE id = " + product.category_id);dan menyematkannya ke dalam hasil (N iterasi sekunder dari kueri kecil dan lambat!)
Total permintaan ke daemon Postgres: 1 + 100 iterasi lokal = 101 jaringan mikro bolak-balik antara Node.js dan DB. 101 perjalanan bolak-balik menyebabkan overhead jaringan yang sangat besar dan latensi yang buruk. Pada skala sebenarnya, N mungkin bukan 100 tetapi 10.000 baris total faktur untuk dijelajahi! API tidak akan kembali sebelum mencapai batas waktu 5xx.
Jawaban Asli Sebenarnya: GABUNG atau Agregasi dalam Satu Query
Dengan mahir menggunakan abstraksi DBMS yang ditulis dengan tangan, alih-alih perintah ORM yang sepele di Node, menggabungkan eksekusi bersama-sama dalam milidetik dalam satu kueri tak terkalahkan yang menyelesaikan kekacauan "N+1":
SELECT
p.id,
p.name,
c.name AS category_name
FROM products p
JOIN categories c ON p.category_id = c.id;Total perjalanan bolak-balik API/DB: 1 kueri unik, digabungkan, dioptimalkan secara matematis oleh indeks Postgres sendiri, ditangani seluruhnya dengan latensi jaringan tambahan 0 milidetik.
Alternatif agregasi JSON
Versi Postgres modern bahkan memungkinkan Anda mengembalikan seluruh gabungan kompleks yang disarangkan sebagai JSON dengan json_agg, memungkinkan JavaScript Anda menerima larik products termasuk sub-array ulasan yang diformat tanpa lem skrip lokal! (Di jalur dan tantangan lanjutan Anda akan mempelajari klausa JSONb Postgres.)
Giliranmu
Mari kita selesaikan Masalah N+1 yang sedang dibuat.\nNode akan menjalankan Select global lalu mengulangi setiap pelanggan untuk menemukan nama mereka jika ingin rekap pesanan yang dikirim pagi ini.\nSelesaikan dengan mencetak saya dalam satu gambar asli GABUNG antara 'pelanggan' (gunakan alias tekstual asli 'c') dan 'pesanan' (alias 'o').\nEkstrak 2 bidang sepele (memaksa awalan alias formal): 'c.first_name' (dari pelanggan) dan 'o.status' (dari pending order).
Tunjukkan petunjuk
Sintaks: PILIH c.nama_pertama, o.status DARI pelanggan c GABUNG pesanan o ON c.id = o.customer_id;
Solusi tersedia setelah 3 upaya
Menjelajahi efisiensi GROUP BY
Jika Group-By yang logis tidak digunakan di dalam database untuk mendapatkan jumlah total per baris dan kategori, Node.js akan memanggil DB tanpa henti, membengkak menjadi N+1.\nTulis satu kueri yang memilih bidang 'kota' dari 'pelanggan' dan jumlah Postgres standar 'COUNT(id)' menggunakan kata kunci terminal untuk mengagregasinya secara unik berdasarkan nama.
Tunjukkan petunjuk
Hal sepele: PILIH kota, COUNT(id) DARI pelanggan KELOMPOK BERDASARKAN kota;
Solusi tersedia setelah 3 upaya