W poprzedniej części pokazałem wstępnie, jak radzić sobie z bazą danych w Magento. A teraz skomplikujmy jeszcze sytuację pobierając wiele danych i popełniając najcięższy grzech programisty Magento czyli pobierajmy kolejne dane w pętli poprzez load (aż zimny dreszcz przeszedł mi po plecach).

ORM – płaska struktura tabeli (wiele danych – load w pętli)

W kontekście stworzonej wcześniej płaskiej struktury tabeli wykonajmy poniższy kod:

16

Widzimy tu pobranie danych poprzez load jak w przykładzie wcześniejszym, jednak całość odbywa się teraz w pętli. Wynikiem jest wyświetlenie danych mieszkańców:
17

A ORM wykonał następujące operacje SQL:18

Jak się łatwo domyślić przy każdej iteracji pętli ORM składał od nowa to samo zapytanie tylko z innym id w warunku.

Powyższy przykład jest najczęściej popełnianym błędem programistów Magento wpływającym na wydajność. Każdy bowiem powinien wiedzieć, że do tego typu operacji służą właśnie kolekcje.

ORM – płaska struktura tabeli (wiele danych – kolekcje)

Poprawmy więc poprzedni kod:
19

Tym razem po odwołaniu się do modelu divante_training/residents pobieramy kolekcje mieszkańców. Następnie deklarujemy, że potrzebne są nam dwa atrybuty – imię i nazwisko – a na końcu filtrujemy naszą kolekcje po id-kach.

Wynik jest ten sam (wyświetlenie imion i nazwisk mieszkańców) jednak to co zrobił ORM różni się znacznie od tego co było wcześniej:20

Widzimy, że zamiast tego samego, powielonego zapytania zostało sklejone jedno zwracające nam potrzebne dane, dzięki czemu wydajność aplikacji nam wzrosła.

A co się będzie działo gdy analogiczny błąd wydajnościowy powtórzymy z EAV ? 

ORM – EAV (wiele danych – load w pętli)

Oto przykład kodu ładującego dane mieszkańców w pętli przy strukturze tabel EAV:

21

A to wynik pracy ORM:22

Jest to najgorszy przypadek wydajnościowy w kodzie Magento. W każdej iteracji pętli bowiem tworzymy od nowa kilka zapytań do tabel EAV. Tylko pierwsze zapytanie pobierające typ encji EAV jest wykonywane raz, wszystkie pozostałe są sklejane w każdej iteracji pętli od nowa.

Jeżeli w naszym kodzie przetwarzalibyśmy więcej danych (np. 200 produktów) to spadek wydajności widzielibyśmy gołym okiem, bez potrzeby uruchamiania profilera.

Nie czekajmy więc dłużej i poprawmy nasz kod.

ORM – EAV (wiele danych – kolekcja)

23

Powyższy kod odwołuje się do modelu divante_barcamp/residents  i pobiera kolekcję mieszkańców. Potrzebujemy tylko imię i nazwisko mieszkańca, a listę potrzebnych mieszkańców filtrujemy po posiadanych id-kach.

Wyświetlany efekt nie różni się od poprzednich jednak ORM odsapnął:24

Widzimy powyżej wyraźnie, że zamiast dublowania tych samych zapytań w każdej iteracji, zapytania zostały sklejone i filtrowane o potrzebne nam elementy.

Dodatkowo chciałbym zwrócić uwagę, że ostatnie zapytanie różni się od tego, które wykonaliśmy poprzednio tym jeszcze, że odwołujemy się tylko do tabeli resident_entity_varchar (nie ma nigdzie znaku po tabeli resident_entity_int). Zadziało się tak, ponieważ oba typy danych które potrzebowaliśmy (imię i nazwisko) są typu VARCHAR i nie ma potrzeby sięgania do innych tabel bo nie ma tam atrybutów, które by nas mogły interesować.

Przy kolekcjach trzeba więc pamiętać by zawsze wypisać listę potrzebnych atrybutów, bo jeżeli nie wpiszemy ich jawnie to ORM ich nam po prostu nie zwróci. 

Podsumowanie

Mam nadzieje, że powyższe przykłady ukazały Wam różnice między płaską tabelą a EAV nie tylko w aspekcie projektowym, ale przede wszystkim wydajnościowym.

W każdym zbudowanym module Magento należy zwracać uwagę na to, z jaką konfiguracją się pracuje i w jaki sposób przetwarzane są dane.

Aby utwierdzić w Was przekonanie wrażliwości na wydajność posłużę się wykresem:

25

Wykres pokazuje różnice w przetwarzaniu produktów (EAV) w pętli poprzez load oraz poprzez kolekce (czyli przytoczone wcześniej przykłady).

Widzimy tu wyraźnie, że load w pętli powoduje liniowy spadek wydajności. Posłużenie się kolekcją natomiast praktycznie nie wpływa na spadek wydajności.

Mam nadzieję, że teraz poradzicie sobie z bazą danych bez problemów. Już niedługo kolejne wskazówki do pracy na Magento!