Um desenvolvedor Magento substituiu 300 chamadas separadas de ProductRepositoryInterface::getById() por uma única consulta de coleção. As requisições ao banco de dados caíram de 300 para 1, e a página de categoria carregou visivelmente mais rápido. A contrapartida? Alguns produtos desapareceram da loja virtual, confundindo clientes e proprietários.

O problema N+1 em uma página de categoria Magento

A página listava 300 produtos. Para cada um, o código buscava dois atributos personalizados por meio do método getById() do repositório, gerando uma consulta por produto — o clássico padrão N+1. Substituir essas cargas por produto por uma coleção que busca todas as linhas necessárias em uma única consulta reduziu drasticamente o número de consultas. A latência do front-end melhorou, mas a lista de produtos agora omitia itens que apareciam anteriormente.

Por que a coleção oculta itens fora de estoque

O módulo CatalogInventory do Magento adiciona automaticamente um filtro de "em estoque" a qualquer coleção de produtos construída para o front-end. O filtro é ativado quando a configuração da loja Display Out of Stock Products está desativada, uma escolha comum para lojistas que não desejam exibir itens indisponíveis.

Em contrapartida, o repositório nunca aplica um filtro de estoque. Ele simplesmente verifica se um produto existe e o retorna, independentemente do nível de inventário. Quando o código mudou de chamadas de repositório para uma coleção, o filtro de estoque removeu silenciosamente cada produto cuja quantidade era zero. Nenhum erro foi registrado; a coleção apenas retornou menos linhas do que o desenvolvedor esperava.

O que isso significa para os lojistas

Uma loja virtual que remove silenciosamente SKUs fora de estoque cria vários problemas:

  • Componentes de front-end recebem entradas ausentes, produzindo rótulos vazios ou preços incorretos.
  • A depuração torna-se mais difícil porque o sintoma — produtos ausentes — não gera avisos.

Como a maioria dos testes automatizados utiliza fixtures de itens em estoque, o erro geralmente permanece oculto até que o site seja executado com o inventário real.

Como manter a velocidade sem ocultar o inventário

  1. Pule o filtro de estoque padrão – Remova explicitamente o filtro da coleção se você precisar de todos os produtos, independentemente da disponibilidade. O Magento oferece métodos para desativar ou substituir o plugin de estoque por consulta.
  2. Use o repositório quando a precisão for importante – O repositório garante que cada ID de produto solicitado seja retornado, mesmo que esteja fora de estoque. Faça o cache dos resultados ou carregue apenas os IDs de que precisa para controlar as consultas extras.
  3. Utilize um resource model ou SQL puro – Consulte a tabela de produtos diretamente para obter os atributos necessários. Isso ignora todos os plugins de coleção e oferece controle total sobre quais linhas são incluídas.

Velocidade versus correção

Substituir um loop N+1 ruidoso por uma única consulta de coleção parece natural; a queda na latência é tangível. No entanto, uma consulta mais rápida que retorna o conjunto errado de produtos é um defeito, não uma otimização. Os desenvolvedores devem pesar a velocidade bruta contra o risco de exibir um catálogo incompleto.

O que observar a seguir

  • Desvio de configuração – Verifique se a flag Display Out of Stock Products corresponde ao comportamento pretendido de qualquer código de coleção personalizado.
  • Efeitos colaterais de plugins – Outros módulos podem adicionar seus próprios filtros às coleções. Revise a pilha de plugins sempre que alterar as estratégias de consulta.

A lição é clara: corrigir um problema de N+1 com uma coleção só vale a pena se você também auditar os filtros padrão da coleção. Ignorar o filtro de estoque integrado do Magento pode podar silenciosamente seu catálogo, transformando um ganho de desempenho em perda de receita.