Seorang pembangun Magento telah menggantikan 300 panggilan ProductRepositoryInterface::getById() yang berasingan dengan satu pertanyaan koleksi. Capaian pangkalan data menurun daripada 300 kepada 1, dan halaman kategori dimuatkan dengan jauh lebih pantas. Kesannya? Beberapa produk hilang daripada kedai dalam talian, sehingga mengelirukan pembeli dan pemilik.

Masalah N+1 pada halaman kategori Magento

Halaman tersebut menyenaraikan 300 produk. Bagi setiap produk, kod tersebut mengambil dua atribut tersuai melalui kaedah getById() repositori, yang menghasilkan satu pertanyaan bagi setiap produk—corak N+1 yang klasik. Menggantikan muatan setiap produk tersebut dengan koleksi yang menarik semua baris yang diperlukan dalam satu pertanyaan telah mengurangkan jumlah pertanyaan secara drastik. Latensi bahagian hadapan (front-end) bertambah baik, tetapi senarai produk kini kehilangan item yang sebelum ini dipaparkan.

Mengapa koleksi menyembunyikan item yang kehabisan stok

Modul CatalogInventory Magento secara automatik menambah penapis "in-stock" kepada mana-mana koleksi produk yang dibina untuk bahagian hadapan. Penapis ini diaktifkan apabila tetapan kedai Display Out of Stock Products dimatikan, satu pilihan biasa bagi peniaga yang tidak mahu memaparkan item yang tidak tersedia.

Sebaliknya, repositori tidak pernah mengenakan penapis stok. Ia hanya menyemak sama ada sesuatu produk itu wujud dan mengembalikannya, tanpa mengira tahap inventori. Apabila kod beralih daripada panggilan repositori kepada koleksi, penapis stok secara senyap telah membuang setiap produk yang kuantitinya adalah sifar. Tiada ralat dicatatkan; koleksi tersebut hanya mengembalikan baris yang lebih sedikit daripada yang dijangkakan oleh pembangun.

Apa maksudnya bagi peniaga

Kedai dalam talian yang membuang SKU yang kehabisan stok secara senyap mewujudkan beberapa masalah:

  • Komponen bahagian hadapan menerima entri yang hilang, menghasilkan label kosong atau harga yang salah.
  • Proses penyahpepijatan (debugging) menjadi lebih sukar kerana simptomnya—produk yang hilang—tidak menghasilkan sebarang amaran.

Oleh kerana kebanyakan ujian automatik menggunakan fixtures yang mempunyai stok, pepijat ini sering kali tersembunyi sehingga laman web beroperasi dengan inventori sebenar.

Cara mengekalkan kelajuan tanpa menyembunyikan inventori

  1. Langkau penapis stok lalai – Buang penapis tersebut daripada koleksi secara eksplisit jika anda memerlukan setiap produk tanpa mengira ketersediaan. Magento menawarkan kaedah untuk menyahaktifkan atau menggantikan plugin stok bagi setiap pertanyaan.
  2. Gunakan repositori apabila ketepatan adalah penting – Repositori menjamin bahawa setiap ID produk yang diminta akan dikembalikan, walaupun ia kehabisan stok. Simpan hasil dalam cache atau muat turun hanya ID yang anda perlukan untuk mengawal jumlah pertanyaan tambahan.
  3. Gunakan model sumber (resource model) atau SQL mentah – Buat pertanyaan pada jadual produk secara terus untuk mendapatkan atribut yang diperlukan. Ini memintas semua plugin koleksi dan memberi anda kawalan penuh ke atas baris mana yang disertakan.

Kelajuan berbanding ketepatan

Menggantikan gelung N+1 yang "bising" dengan satu pertanyaan koleksi terasa semula jadi; penurunan latensi adalah nyata. Namun, pertanyaan yang lebih pantas tetapi mengembalikan set produk yang salah adalah satu kecacatan, bukannya pengoptimuman. Pembangun mesti menimbang kelajuan mentah berbanding risiko memaparkan katalog yang tidak lengkap.

Apa yang perlu diperhatikan seterusnya

  • Penyimpangan konfigurasi (Configuration drift) – Sahkan bahawa bendera Display Out of Stock Products sepadan dengan tingkah laku yang dikehendaki bagi mana-mana kod koleksi tersuai.
  • Kesan sampingan plugin – Modul lain mungkin menambah penapis mereka sendiri kepada koleksi. Semak timbunan plugin (plugin stack) setiap kali anda menukar strategi pertanyaan.

Pengajarannya jelas: membaiki isu N+1 dengan koleksi hanya akan membuahkan hasil jika anda juga menyemak penapis lalai koleksi tersebut. Mengabaikan penapis stok terbina dalam Magento boleh memangkas katalog anda secara senyap, menukarkan peningkatan prestasi kepada kerugian hasil.