Dzisiaj o odkrywaniu Ameryki w konserwie. Właśnie takie miałem wrażenie, gdy dłubiąc w projekcie trafiłem na rozdział na temat cache w dokumentacji Doctrine. Wcześniej tam nie trafiłem, bo całe keszowanie robiłem w Symfony – wszak do pamięci podręcznej najlepiej wrzucać efekt końcowy. Dodatkowo w dokumentacji Symfony nie rzuciło mi się w oczy nic na temat cacheowania w Doctrine.
Nie zamierzam streszczać dokumentacji Doctrine. W kontekście tej notki ważne jest, że Doctrine może zapamiętywać w cache dwa rodzaje danych:
- skompilowane zapytania
- wyniki zapytań
Dzięki zapamiętywaniu zapytań czasochłonny proces parsowania zapytania i budowania docelowej SQL-ki jest wykonywany tylko raz, kolejne wywołania będą korzystać z danych zapamiętanych w pamięci podręcznej. Problem aktualności danych w cache nie istnieje ponieważ zmiana zapytania spowoduje automatyczne wygenerowanie nowych danych. Korzyści są niebagatelne, użycie proste jak konstrukcja cepa, a problemów nie ma. Dlatego zgodnie z dokumentacją i zdrowym rozsądkiem, pamięć podręczna zapytań powinna być zawsze włączona, nawet w środowisku testowym.
Włączenie cache dla Doctrine w projekcie Symfony jest banalne i sprowadza się do dodania króciutkiej metody w klasie config/ProjectConfiguration.class.php
.
public function configureDoctrine(Doctrine_Manager $manager) { $manager->setAttribute(Doctrine_Core::ATTR_QUERY_CACHE, new Doctrine_Cache_Apc()); }
Powyższy kod spowoduje, że skompilowane zapytania będą zapamiętywane w pamięci APC. Oprócz APC Doctrine może współpracować z serwerem memcached lub inną bazą danych (np. SQLite).
Cache można włączyć nie tylko na poziomie managera, równie dobrze można zrobić to w samym zapytaniu:
$q = Doctrine_Query::create() ->useQueryCache(new Doctrine_Cache_Apc());
Jak wspomniałem wcześniej, pamięć podręczna zapytań powinna być włączona zawsze. Na poziomie konkretnego zapytania więcej sensu ma włączanie zapamiętywania wyników:
$q = Doctrine_Query::create() ->useResultCache(new Doctrine_Cache_Apc());
Bardzo fajnie napisany art. Prosto i łopatologicznie :)
Dzięki tego szukałem :)
Witam,
nie rozumiem jednego, że problem aktualności danych nie istnieje. Załóżmy, że zapytanie wyciągające listę rekordów się pobierze jakieś dane a potem te dane zostaną zmienione. Przy kolejnym pobraniu listy rekordów zapytanie się nie zmieni. Co wtedy ? Jak jest aktualizowana lista rekordów ?
@Tom
Problem aktualności danych nie istnieje w wypadku keszowania zapytania (query cache). Opisywany przez Ciebie problem występuje w wypadku keszowania wyniku zapytania (result cache).