Bir Magento geliştiricisi, 300 ayrı ProductRepositoryInterface::getById() çağrısını tek bir koleksiyon sorgusuyla değiştirdi. Veritabanı istekleri 300'den 1'e düştü ve kategori sayfası fark edilir derecede daha hızlı yüklendi. Peki, bunun bedeli ne oldu? Bazı ürünler mağaza sayfasından kayboldu; bu durum hem müşterilerin hem de mağaza sahiplerinin kafasını karıştırdı.
Bir Magento kategori sayfasındaki N+1 problemi
Sayfa 300 ürün listeliyordu. Kod, her bir ürün için repository'nin getById() metodu aracılığıyla iki özel öznitelik (custom attribute) getiriyor ve ürün başına bir sorgu oluşturuyordu; bu, klasik N+1 desenidir. Bu ürün bazlı yüklemeleri, gerekli tüm satırları tek bir sorguda çeken bir koleksiyonla değiştirmek sorgu sayısını büyük ölçüde azalttı. Ön uç (front-end) gecikmesi iyileşti ancak ürün listesi, daha önce görünen bazı öğeleri artık göstermiyordu.
Koleksiyon, stokta olmayan ürünleri neden gizler?
Magento'nun CatalogInventory modülü, ön uç için oluşturulan herhangi bir ürün koleksiyonuna otomatik olarak bir "stokta var" (in-stock) filtresi ekler. Bu filtre, mağaza ayarlarındaki Display Out of Stock Products seçeneği kapatıldığında devreye girer; bu, mevcut olmayan ürünleri göstermek istemeyen satıcılar için yaygın bir tercihtir.
Buna karşılık, repository hiçbir zaman bir stok filtresi uygulamaz. Envanter seviyesine bakmaksızın sadece ürünün var olup olmadığını kontrol eder ve onu döndürür. Kod, repository çağrılarından bir koleksiyona geçtiğinde, stok filtresi miktarı sıfır olan tüm ürünleri sessizce eledi. Hiçbir hata günlüğe kaydedilmedi; koleksiyon sadece geliştiricinin beklediğinden daha az satır döndürdü.
Bu durum satıcılar için ne anlama geliyor?
Stokta olmayan SKU'ları sessizce düşüren bir mağaza sayfası birkaç soruna yol açar:
- Ön uç bileşenleri eksik girişler alır, bu da boş etiketlere veya yanlış fiyatlandırmaya neden olur.
- Hata ayıklama (debugging) zorlaşır çünkü belirti olan "eksik ürünler" herhangi bir uyarı oluşturmaz.
Çoğu otomatize test stokta olan verileri (fixtures) kullandığı için, hata genellikle site gerçek envanterle çalışana kadar gizli kalır.
Envanteri gizlemeden hızı nasıl korursunuz?
- Varsayılan stok filtresini atlayın – Eğer kullanılabilirlikten bağımsız olarak her ürüne ihtiyacınız varsa, filtreyi koleksiyondan açıkça kaldırın. Magento, sorgu başına stok eklentisini (plugin) devre dışı bırakmak veya değiştirmek için yöntemler sunar.
- Doğruluk önemli olduğunda repository kullanın – Repository, stokta olmasa bile talep edilen her ürün kimliğinin (ID) döndürüleceğini garanti eder. Ek sorguları dizginlemek için sonuçları önbelleğe alın veya yalnızca ihtiyacınız olan kimlikleri yükleyin.
- Bir resource model veya ham SQL kullanın – Gerekli öznitelikler için doğrudan ürün tablosunu sorgulayın. Bu, tüm koleksiyon eklentilerini devre dışı bırakır ve hangi satırların dahil edileceği konusunda size tam kontrol sağlar.
Hız ve doğruluk karşı karşıya
Gürültülü bir N+1 döngüsünü tek bir koleksiyon sorgusuyla değiştirmek doğal hissettirir; gecikmedeki düşüş somuttur. Ancak yanlış ürün setini döndüren daha hızlı bir sorgu bir optimizasyon değil, bir hatadır (defect). Geliştiriciler, ham hızı, eksik bir katalog gösterme riskiyle tartmalıdır.
Bir sonraki adımda nelere dikkat edilmeli?
- Yapılandırma sapması (Configuration drift) – Display Out of Stock Products bayrağının, özel koleksiyon kodunun amaçlanan davranışı ile eşleştiğini doğrulayın.
- Eklenti yan etkileri (Plugin side effects) – Diğer modüller koleksiyonlara kendi filtrelerini ekleyebilir. Sorgu stratejilerini her değiştirdiğinizde eklenti yığınını (plugin stack) gözden geçirin.
Ders açık: Bir N+1 sorununu bir koleksiyonla çözmek, ancak koleksiyonun varsayılan filtrelerini de denetlerseniz kazanç sağlar. Magento'nun yerleşik stok filtresini göz ardı etmek, kataloğunuzu sessizce budayabilir ve bir performans kazancını gelir kaybına dönüştürebilir.
