Symfony admin generator – optymalizacja zapytań do bazy dla Doctrine
17 February 2009Ostatnio w projekcie Symfony 1.1 z użyciem Doctrine, dzięki webdebug toolbarowi, dostrzegłem czegoś, co mnie przeraziło. Otóż, jeśli w wygenerowanym przez Symfony adminie mamy klucze obce na liście, to wywoła on tyle zapytań ile elementów * ilość kluczy obcych.
Załóżmy, że mamy następujący schemat:
Kategoria:
columns:
nazwa: string(255)
Produkt:
columns:
nazwa: string(255)
kategoria_id: integer
relations:
kategoria:
class: Kategoria
Natomiast w generator.yml mamy zdefiniowane:
generator: class: sfDoctrineAdminGenerator param: model_class: Produkt theme: default list: display: [nazwa,kategoria]
To w przypadku kategoria, generator będzie wywoływał zapytanie w stylu
select * from kategoria where id = ?
co przy domyślnych 20 rekordach na stronę i przykładowo 3 kluczach obcych wygeneruje ponad 60 zapytań. Tego prawdopodobnie nie chcemy.
Rozwiązaniem w tej sytuacji jest zastosowanie parametru peer_method (znanego mi jeszcze z czasów używania Propela), znajdujące się w sekcji list.
Występuje tu jednak kilka założeń, o których warto wiedzieć. Po pierwsze: metoda którą określamy w peer_method musi znajdować się w klasie wskazanej w model_class (w naszym przypadku Produkt) i nie może być to metoda statyczna. Po drugie: metoda ta musi zwracać instancję klasy Doctrine_Query. Po trzecie, metoda ta musi mieć zakończenie nazwy pod postacią TableProxy. Po czwarte (tu tkwi największy trick): w złączeniach DQL nie możemy używać własnych aliasów, tylko aliasować pełnymi nazwami klas.
Oto przykład:
plik /lib/model/doctrine/Produkt.class.php
class Produkt extends BaseProdukt
{
public function polaczZKategoriamiTableProxy()
{
return Doctrine_Query::create()->from('Produkt')->innerJoin('Produkt.kategoria'); //->from('Produkt p')->innerJoin('p.kategoria') jest błędne!
}
}
plik /apps/backend/modules/produkty/config/generator.yml
generator:
class: sfDoctrineAdminGenerator
param:
model_class: Produkt
theme: default
list:
peer_method: polaczZKategoriami
display: [nazwa,kategoria]
Dzięki temu w znaczynym stopniu ograniczymy zapytania do bazy :-)
edit: już wkrótce to rozwiązanie tego samego problemu dla Symfony 1.2 (tam niestety zrezygnowano z peer_method).
Podobne wpisy
-
http://www.xsolve.pl/ Przemysław Piechota
-
http://www.jacek.jedrzejewski.name eXtreme
-
http://www.jacek.jedrzejewski.name eXtreme
-
janek
-
http://www.fora4you.pl zajefajnyx
About modern web technologies