Wpis z mikrobloga

Witajcie.
Jest taka sytuacja. Korzystając z #symfony2 i #doctrine pobieram rekordy z bazy danych. Używam zarówno find(), findAll(), findOneBy() itd. Piszę też zapytania do db korzystając z query builder. Wydaje mi się jednak, że mam za dużo zapytań do bazy danych. Na jednej stron mam 36 zapytań do bazy danych , mimo że tam wyświetlam tylko statystykę o produktach i użytkownikach (użytkownik - ilość głosów, produkt - ilość głosów).
W poprzedniej pracy pracując z Yii1 nie miałem takiego debuggera jaki jest w sf2 (tzn. miałem ale nie korzystałem), więc nie wiem ile tam było zapytań, ale ogólnie to polegał na tym, że używawjąc join, leftJoin wyciągałem wszystko jednym zapytaniem, a potem operowałem na tablicy rezultatów.
Tutaj natomiast mam wrażenie, że doctrine dociąga informację podczas wyświetlania jej w #twigu, ponieważ w debuggerze mam masę takich samych zapytań, różniących się tylko parametrem. np. tu część zapytań: http://i.share.pho.to/9a99d6e0_o.png

Jak zrobić, żeby informacja nie była pobierana w DB w taki sposób, a np. jednym zapytaniem. Może jest jakiś dobry artykuł?

#php #webdev #symfony2 #doctrine #db
  • 11
@Klopsztanga: Też myślałem o tym, że to obrazki mogą powodować narastanie zapytań do DB. Hm… sytuacja jest taka, że Produkt ma wiele obrazków, a muszę wyświetlić tylko jeden. W tym celu, w encji Product stworzyłem metodę getMainImage(), która pobiera pierwszy obrazek z wielu, jako ten główny.
Hm… teraz akurat wpadłem na taką myśl, że wystarczy pobrać wszystkie obrazki korzystając z JOIN i w twigu użyć filter first, żeby uzyskać ten sam
@mariecziek: powinieneś utworzyć kolumnę $cover , gdzie przechowasz "thumbnail" dla produktu, czyli ten 1 obrazek. Zrób to teraz, zanim będzie za późno, bo będziesz żałować w późniejszym czasie - sprawdzone info
@mariecziek: joiny panie, joiny, poza tym jeśli to do wyświetlania ma być tylko to proponuje skorzystać z partiali i pozbyć się hydracji do obiektów(tj korzystać z Query::HYDRATE_ARRAY/getArrayResult)(a jeszcze lepiej HYDRATE_NONE jak nie masz joinów, co prawda musisz wtedy korzystać z nazw takich jak bazie ale jeszcze więcej zyskujesz na wydajności)

http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/reference/partial-objects.html
@Jurigag: Wiem, że joiny. Widzisz, myślałem, że w SF wystarczy opisać relacje w Encji i Joiny będą tworzone automatycznie, a okazuje się, że korzystajć z query buildera, muszę znowu pisać Joiny, bo zapytania do bazy danych rosną lawinowo.
@mariecziek: nie, nie musisz pisać "joinów" jako takich, ale musisz napisać że chcesz dołączyć coś, relacje są po to że nie musisz pisać warunków ON, dołączać modeli itp itd tylko robisz sobie po prostu:

->leftJoin('żródłojoina.cojoin','alias')
i tyle, cała reszta się dzieje tak jak napisałeś - automatycznie, skąd symfony(czy jakiwkolwiek inny język i fw) ma się domyśleć że będziesz uzyskiwał dostęp do tego cojoin ? ma sprawdzać to sobie w widoku najpierw
@Jurigag: Rozumiem. No a jeżeli chcę pobrać z bazy danych wszystkie rekordy używając findBy()? Np mam takie coś:

$product = $em->getRepository(Product::class)->findBy(['onSale' => true]);
Żeby zapobiec powielaniu się zapytań, muszę napisać własną metodę do pobierania danych?