Een Magento-ontwikkelaar verving 300 afzonderlijke ProductRepositoryInterface::getById()-aanroepen door één enkele collection query. Het aantal database-aanroepen daalde van 300 naar 1, en de categoriepagina laadde merkbaar sneller. De keerzijde? Sommige producten verdwenen uit de webshop, tot verbazing van zowel klanten als eigenaren.
Het N+1-probleem op een Magento-categoriepagina
De pagina toonde 300 producten. Voor elk product haalde de code twee aangepaste attributen op via de getById()-methode van de repository, wat resulteerde in één query per product — het klassieke N+1-patroon. Door deze individuele product-laadacties te vervangen door een collection die alle benodigde rijen in één query ophaalt, werd het aantal queries drastisch verminderd. De front-end latentie verbeterde, maar de productlijst miste nu items die voorheen wel zichtbaar waren.
Waarom de collection artikelen die niet op voorraad zijn verbergt
De CatalogInventory-module van Magento voegt automatisch een "in-stock"-filter toe aan elke product-collection die voor de frontend wordt opgebouwd. Het filter wordt geactiveerd wanneer de winkelinstelling Display Out of Stock Products is uitgeschakeld, een veelvoorkomende keuze voor webwinkeliers die geen niet-beschikbare artikelen willen tonen.
In tegenstelling hiermee past de repository nooit een voorraadfilter toe. Deze controleert simpelweg of een product bestaat en geeft het terug, ongeacht het voorraadniveau. Toen de code overstapte van repository-aanroepen naar een collection, verwijderde het voorraadfilter stilletjes elk product waarvan de voorraad nul was. Er werd geen fout gelogd; de collection gaf simpelweg minder rijen terug dan de ontwikkelaar had verwacht.
Wat dit betekent voor webwinkeliers
Een webshop die stilletjes artikelen die niet op voorraad zijn verwijdert, veroorzaakt verschillende problemen:
- Front-end componenten ontvangen ontbrekende gegevens, wat resulteert in lege labels of onjuiste prijzen.
- Debuggen wordt moeilijker omdat het symptoom — ontbrekende producten — geen waarschuwingen genereert.
Omdat de meeste geautomatiseerde tests gebruikmaken van "in-stock" fixtures, blijft de bug vaak verborgen totdat de site draait met de werkelijke voorraad.
Hoe snelheid te behouden zonder de voorraad te verbergen
- Sla het standaard voorraadfilter over – Verwijder het filter expliciet uit de collection als je elk product nodig hebt, ongeacht de beschikbaarheid. Magento biedt methoden om de stock-plugin per query uit te schakelen of te vervangen.
- Gebruik de repository wanneer nauwkeurigheid belangrijk is – De repository garandeert dat elk opgevraagd product-ID wordt geretourneerd, zelfs als het niet op voorraad is. Cache de resultaten of laad alleen de ID's die je nodig hebt om het aantal extra queries te beperken.
- Gebruik een resource model of raw SQL – Query de producttabel direct voor de benodigde attributen. Hiermee omzeil je alle collection-plugins en heb je volledige controle over welke rijen worden opgenomen.
Snelheid versus juistheid
Het vervangen van een luidruchtige N+1-loop door een enkele collection query voelt natuurlijk aan; de afname in latentie is tastbaar. Toch is een snellere query die de verkeerde set producten teruggeeft een defect, geen optimalisatie. Ontwikkelaars moeten de pure snelheid afwegen tegen het risico van het tonen van een onvolledige catalogus.
Waar je voortaan op moet letten
- Configuration drift – Controleer of de Display Out of Stock Products-vlag overeenkomt met het beoogde gedrag van eventuele aangepaste collection-code.
- Bijwerkingen van plugins – Andere modules kunnen hun eigen filters aan collections toevoegen. Controleer de plugin-stack telkens wanneer je de query-strategieën wijzigt.
De les is duidelijk: het oplossen van een N+1-probleem met een collection is alleen een winst als je ook de standaardfilters van de collection controleert. Het negeren van de ingebouwde voorraadfilter van Magento kan je catalogus stilletjes inkrimpen, waardoor een prestatiewinst verandert in een omzetverlies.
