Wpis z mikrobloga

Tak mnie ostatnio zastanawia w #laravel dlaczego relacje w ORM wywołują tyle zapytań. Wychodzi na to jakby zapytania były tworzone w pętli. W pracy na co dzień korzystamy z cake i tam też na niektórych podstronach potrafimy mieć po 100 zapytań, gdzie tak naprawdę mamy wywołanie jednej funkcji i podpięcie kilku relacji, potem to wyświetlenie w pętli foreach, ale w pętli nie wrzucamy żadnych zapytań, a przynajmniej ja. :) Kiedyś czytałem, że nie powinno tego się praktykować i ilość zapytań powinna być jak najmniejsza, ale obecne frameworki walą zapytań do bazy danych mnóstwo, więc jak to z tym jest? Już nieaktualne? Już hostingodawcy nie mają limitów zapytań do bazy?

#programowanie #programista15k #php
  • 10
  • Odpowiedz
  • Otrzymuj powiadomienia
    o nowych komentarzach

@nophp: duża ilość zapytań wynika wyłącznie z nieprawidłowo napisanego kodu. Jest to błąd, problem wydajnościowy który powinien zostać naprawiony. To że serwer wytrzyma, to że nie ma żadnych limitów nie zmienia faktu, że da się to zrobić lepiej. Poczytaj o N+1 problem. W ORM pewnie leci jakiś lazy load w pętli.
  • Odpowiedz
@nophp: Trzeba optymalizować zapytania. Jak masz encję, która ma relacje z innymi obiektami, to w metodach takiego modelu bądź w repozytorium domyślne funkcje pobierają tylko podstawowe dane, bez danych powiązanych. Przekładając to czysty SQL, to po prostu bez "JOIN", a zamiast tego nawet i kilkaset zapytań. Im bardziej złożona struktura tym więcej.

Najlepiej samemu napisać zapytanie przy pomocy jakiegoś QueryBuilder'a, którego zwrotem będą encje zgodnie z ORM. Dobrze napisany kod
  • Odpowiedz
@nophp: chcesz wyświetlić 20 komentarzy na mirko:

SELECT * from mirko_comments
to przemiela ORM na 20 obiektów klasy MirkoComment

ale do każdego komentarza chcesz wyświetlić informacje
  • Odpowiedz
rozwiązanie: do pierwszego zapytania dokleić autorów JOINem. tak, ORMem też da się.


@MacDada: w #laravel (bo o to pytał autor), a właściwie Eloquent nic nie musisz doklejać joinem. Metoda with() eager loaduje relacje, ale w przeciwieństwie do Dotrine dociąga je osobnym zapytaniem przy udziale whereIn po IDkach kolekcji.
  • Odpowiedz
  • 1
@nowiutki o kurde mireczku, muszę obczaić tego debugera co podrzuciłes.
Zazwyczaj korzystałem z debugbara od baryvdh, ale były straszne jazdy z zamulaniem.
Dzięki!
  • Odpowiedz
Metoda with() eager loaduje relacje


@nowiutki: pod warunkiem że pobierasz obiekty głównego zapytania wszystkie na raz (za pomocą ->get()), bo jak zrobisz ->cursor() to się te relacje nie załadują
  • Odpowiedz
@Ysior: też go kiedyś używałem, ale clockwork lepszy bo możesz debugować również joby w kolejce. Oraz ma plugin pod Firefoxa więc żadnego cssowego/jsowego debugbara nie wciska w kod strony.
  • Odpowiedz
Już hostingodawcy nie mają limitów zapytań do bazy?


@nophp: dodatkowe zapytania to zawsze tragedia, które dodają niepotrzebnej roboty i mocno dodają latency do całego zapytania

dlaczego relacje w ORM wywołują tyle zapytań.


@nophp: bo ORMy takie są. Generyczne klocki poskładane w taki sposób, że robią to co maja robić, ale przy użyciu dużej ilości bazowych zapytań, gdzie pisząć takie zapytanie ręcznie możemy je uszyć na miarę
  • Odpowiedz