PHP / Magento Dev Blog

  • Publikacje
  • O autorze
  • Kontakt

Magento 2 wolno się ładuje – problem N+1 i kolekcje bez limitu

by Henryk Tews / niedziela, 14 czerwca 2026 / Opublikowano w Magento / Adobe Commerce

Strona kategorii ładowała się 18 sekund przy 200 produktach. PageSpeed score: 12/100. Problem nie był w serwerze ani Varnishu – był w kodzie modułu który dla każdego produktu wykonywał osobne zapytanie SQL.

Objawy

  • TTFB (Time To First Byte) powyżej 10 sekund
  • Czas ładowania strony kategorii rośnie liniowo z liczbą produktów
  • MySQL slow query log pełen zapytań typu SELECT * FROM catalog_product_entity WHERE entity_id = X
  • Problem tylko na stronach z listą produktów, nie na stronach produktu

Diagnoza

# Włącz MySQL slow query log
# /etc/mysql/conf.d/slow.cnf:
# slow_query_log = 1
# slow_query_log_file = /var/log/mysql/slow.log
# long_query_time = 0.1

# Lub użyj Xdebug profilera
# xdebug.mode = profile
# Otwórz stronę kategorii z XDEBUG_PROFILE=1
# Przeanalizuj cachegrind - znajdź funkcję wywoływaną 200+ razy

Przyczyna

Moduł „powiązanych produktów” ładował dla każdego produktu z listy osobną kolekcję powiązań. Przy 200 produktach = 200 dodatkowych zapytań SQL. Klasyczny problem N+1.

Rozwiązanie

<?php
// Przed - N+1: jedno zapytanie per produkt
foreach ($products as $product) {
    $related = $this->relatedFactory->create()
        ->addFieldToFilter('parent_id', $product->getId())
        ->load(); // ZAPYTANIE SQL dla każdego produktu!
}

// Po - jedno zapytanie dla wszystkich
$productIds = array_map(fn($p) => $p->getId(), $products);
$allRelated = $this->relatedFactory->create()
    ->addFieldToFilter('parent_id', ['in' => $productIds])
    ->setPageSize(1000)
    ->load();

// Zgrupuj po parent_id
$grouped = [];
foreach ($allRelated as $rel) {
    $grouped[$rel->getParentId()][] = $rel;
}

Wynik

Czas ładowania strony kategorii: z 18s do 1.2s. Liczba zapytań SQL: z 215 do 8. PageSpeed: z 12 do 78.

About Henryk Tews

Co możesz przeczytać następne

Magento 2 mixed content – HTTP zasoby blokowane na HTTPS stronie
Service Contracts – Data Interfaces i Repository Pattern
Magento 2 – wygasły klucz API bramki płatności wykryty za późno
  • Publikacje
  • O autorze
  • Kontakt

© 2026 Created by

GÓRA
Zarządzaj zgodą
Aby zapewnić jak najlepsze wrażenia, korzystamy z technologii, takich jak pliki cookie, do przechowywania i/lub uzyskiwania dostępu do informacji o urządzeniu. Zgoda na te technologie pozwoli nam przetwarzać dane, takie jak zachowanie podczas przeglądania lub unikalne identyfikatory na tej stronie. Brak wyrażenia zgody lub wycofanie zgody może niekorzystnie wpłynąć na niektóre cechy i funkcje.
Funkcjonalne Zawsze aktywne
Przechowywanie lub dostęp do danych technicznych jest ściśle konieczny do uzasadnionego celu umożliwienia korzystania z konkretnej usługi wyraźnie żądanej przez subskrybenta lub użytkownika, lub wyłącznie w celu przeprowadzenia transmisji komunikatu przez sieć łączności elektronicznej.
Preferencje
Przechowywanie lub dostęp techniczny jest niezbędny do uzasadnionego celu przechowywania preferencji, o które nie prosi subskrybent lub użytkownik.
Statystyka
Przechowywanie techniczne lub dostęp, który jest używany wyłącznie do celów statystycznych. Przechowywanie techniczne lub dostęp, który jest używany wyłącznie do anonimowych celów statystycznych. Bez wezwania do sądu, dobrowolnego podporządkowania się dostawcy usług internetowych lub dodatkowych zapisów od strony trzeciej, informacje przechowywane lub pobierane wyłącznie w tym celu zwykle nie mogą być wykorzystywane do identyfikacji użytkownika.
Marketing
Przechowywanie lub dostęp techniczny jest wymagany do tworzenia profili użytkowników w celu wysyłania reklam lub śledzenia użytkownika na stronie internetowej lub na kilku stronach internetowych w podobnych celach marketingowych.
  • Zarządzaj opcjami
  • Zarządzaj serwisami
  • Zarządzaj {vendor_count} dostawcami
  • Przeczytaj więcej o tych celach
Zobacz preferencje
  • {title}
  • {title}
  • {title}