Symfony admin generator – optymalizacja zapytań do bazy dla Doctrine
Napisane przez wowo | Kategorie: Symfony, php
Ostatnio 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).
Tagi: admin generator, Doctrine, php, Symfony
Podobne wpisy
- Escapowanie % w sprintf
- Symfony Mixins – how to extend symfony core classes without inheritance
- Symfony 1.2 wydane
6 Responses to “Symfony admin generator – optymalizacja zapytań do bazy dla Doctrine”
-
Przemysław Piechota Says:
Kwiecień 8th, 2009 at 17:15W symfony 1.2 nie zrezygnowano całkowicie z peer_method.
Można ją ustawić w klasie NazwaModułuGeneratorConfiguration.class.php która znajduje się w katalogu NazwaModułu/lib/ .
W tej klasie można nadpisać funkcję getPeerMethod() . -
eXtreme Says:
Maj 22nd, 2009 at 08:15Ej sorry ale co ty za głupoty wygadujesz tutaj: “: w złączeniach DQL nie możemy używać własnych aliasów, tylko aliasować pełnymi nazwami klas.”
:O Toż to herezja! Od kiedy niby “nie możemy”? Zawsze można było i się da! -
wowo Says:
Maj 22nd, 2009 at 08:26eXtreme: nie można w przypadku generatora, bo on już sam ustawia alias na starcie…
-
eXtreme Says:
Maj 22nd, 2009 at 13:59Można. :)
Po pierwsze, to chyba zamiast “peer_method”, powinno być “table_method”.
Druga sprawa, to $q->getRootAlias() które pozwala zwrócić domyślnie ustawiony alias dla bazowego modelu.Przykładowy kod jakiego ja używam: (nie wiem czy masz tu możliwość włączenia jakiegoś formatowania, więc wklejam na wklejke :P)
http://wklej.org/hash/14cd5ef3cf/
BTW. Popraw linki pod autorem komentarza bo doklejasz tam atrybut “rel” ale chyba niezbyt prawidłowo. ;)
-
janek Says:
Czerwiec 26th, 2009 at 09:56w generate.yml można ustawić table_method
tam podając, która metoda ma zostać wywołana do pobierania danych.
a jeżeli chodzi o aliasy w zapytaniu to można tak:
$rootAlias = $q->getRootAlias();
$q->leftJoin($rootAlias . ‘.Powiat p’);
return $q; -
zajefajnyx Says:
Listopad 23rd, 2009 at 22:07Chcemy wiecej :D



