Użycie mechanizmu keszującego (ang. cache) jest powszechnie uznawane za jedną z najefektywniejszych metod optymalizacji. Niestety mimo licznych zastosowań często pomija się wykorzystanie tego mechanizmu w celu przechowywania wyników zapytań do baz danych. Tymczasem dzięki wbudowanemu w Doctrine wsparciu dla keszowania możemy łatwo przyspieszyć obsługę zapytań SQL w naszych aplikacjach.
Konfiguracja
Podstawowa konfiguracja polega na ustawieniu odpowiedniej klasy sterownika oraz strategii keszowania. Doctrine dostarcza klasy sterowników dla większości powszechnie używanych mechanizmów keszujących (APC, XCache, memcache) oraz dwie strategie keszowania (keszowanie wyników procesu parsowania zapytań DQL oraz keszowanie wyników zapytań SQL). W zależności od potrzeb konfigurację możemy przeprowadzić globalnie (do wyboru mamy konfigurację managera lub połączeń) lub lokalnie z poziomu konkretnego zapytania.
Pracując z symfony ustawienia globalne najlepiej zdefiniować poprzez dodanie metody configureDoctrine() klasy ProjectConfiguration. W zależności od wybranej strategii rejestrujemy sterownik poprzez ustawienie odpowiedniego atrybutu (Doctrine_Core::ATTR_QUERY_CACHE lub Doctrine_Core::ATTR_RESULT_CACHE). Dodatkowo poprzez ustawienie atrybutu Doctrine_Core::ATTR_*_CACHE_LIFESPAN możemy ustawić czas ważności rekordów.
Powyższa konfiguracja obejmuje wszystkie połączenia nawiązywane przez Doctrine. Czasem może zaistnieć potrzeba ograniczenia konfiguracji do konkretnego połączenia (na przykład jedno z dwóch połączeń jest nawiązywane do bazy danych modyfikowanej przez inną aplikacje). W takiej sytuacji możemy użyć metody configureDoctrineConnectionName() zastępując człon Name nazwą naszego połączenia.
W razie potrzeby konfigurację możemy przeprowadzić z poziomu konkretnego zapytania. Służą do tego metody useQueryCache() oraz useResultCache() (w dalszej części artykułu poznamy szersze zastosowanie tych metod). Konfiguracja lokalna nadpisuje konfigurację globalną.
Keszowanie w praktyce
Mając poprawnie skonfigurowany sterownik jesteśmy gotowi, aby zastosować mechanizm keszujący do naszych zapytań. Kolejne kroki zależą od poziomu konfiguracji oraz wybranej strategii keszownia. Dla przykładu, jeśli wybraliśmy konfigurację globalną oraz keszowanie wyników zapytań, należy powiadomić Doctrine, które zapytania mają być keszowane (keszowanie wyników procesu parsowania DQL jest automatycznie zastosowane do wszystkich zapytań). Służy do tego wczesniej poznana metoda useResultCache(). Metoda ta jako pierwszy parametr przyjmuje instancję sterownika lub wartość logiczną, który informuje czy dane zapytanie ma być objęte mechanizmem keszowania. Drugi parametr określa czas ważności rekordu dla naszego zapytania, natomiast trzeci jest identyfikatorem tego rekordu.
W ten sposób wynik zapytania po pierwszym wykonaniu zostanie umieszczony w mechanizmie keszującym pod nazwą sample_query na okres jednej godziny. W ciągu tej godziny każde kolejne wykonanie zapytania będzie oddelegowane do mechanizmu keszującego.
Przekazując do zapytania dodatkowe parametry, musimy zadbać, aby każdemu ich zestawowi odpowiadał inny ciąg identyfikujacy wynik zapytania. Doctrine automatycznie wygeneruje odpowiedni identyfikator jeśli nie podamy go jawnie. Takie rozwiązanie jest niewygodne jeśli mamy w perspektywie zarządzanie zawartością mechanizmu keszującego (musimy znać idnentyfikator). Więcej o zarządzaniu wynikami operacji keszowania można przeczytać w poniższym paragrafie.
Metoda useQueryCache() poza tym, że nie przyjmuje trzeciego parametru (identyfikatora) działa analogicznie do useResultCache(). Szczegółowe informacje można znaleźć w dokumentacji API.
Co dalej?
Keszowanie wyników zapytań niesie ze sobą pewne niebezpieczeństwo – dane mogą szybko stać się nieaktualne. Wraz ze sterownikami otrzymujemy zestaw metod umożliwiających zarządzanie zawartością mechanizmu keszującego. W połączeniu z mechanizmem zdarzeń możemy automatycznie usuwać skeszowane wyniki, zapewniając sobie w ten sposób aktualność danych.
Wolne od takich problemów jest keszowanie wyników parsowania DQL, które zarządzane jest przez Doctrine automatycznie.
Podsumowanie
Pomimo oczywistych zalet, stosowanie mechanizmu keszującego powinno być dobrze przemyślane. O ile keszowanie sparsowanych zapytań DQL jest bezpieczne (jeśli stosujemy prepared statements) i zaleca się jego użycie w większości projektów, to wykorzystanie skeszowanych wyników zapytań powinno dotyczyć tylko wybranych przypadków, w których ma sens i faktycznie przyniesie nam korzyści. Nie należy zapominać tutaj o zasadzie, że nie wszystko co zostało opisane jako dobra metoda na polepszenie wydajności aplikacji, będzie dawało taki rezultat we wszystkich sytuacjach.
0
komentarzy