![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 898 Pomógł: 48 Dołączył: 2.11.2005 Skąd: Poznań Ostrzeżenie: (0%) ![]() ![]() |
Witam, ostatnio postanowilem sie zajac cachowaniem zapytan z bd. I tak pomalutku stworzylem swoja klase do cachowania/odczytywania zapytan z PostgreSQL. Klasa po malych przerobkach bedzie dzialac rowniez z MySQL.
Na poczatek, co by nie byc posadzony o plagiat (IMG:http://forum.php.pl/style_emoticons/default/biggrin.gif) od razu przyznam sie ze korzystalem z rozwiazania mike_mecha (http://php.nq.pl/index.php?showtopic=22487&hl=cache) - ale oczywiscie tyko pogladowo (IMG:http://forum.php.pl/style_emoticons/default/biggrin.gif) Na poczatek moze diagram mojego rozwiazania Diagram klas (uml znam slabo wiec pewnie sa bledy w diagramie jesli chodzi o oznaczenie relacji) Co do kodu to znajduje sie on tutaj: (podaje linki bo kodu jest za duzo na wklejanie) Klasa DB -glowna klasa bazy danych Db_result - abstrakcyjna klasa wyniku zapytania Db_Result_orig - wynik zapytania wykonanego z bazy Db_result_cache - wynik zapytania wykonanego z cachu (lub z bazy z pozniejszym cachowaniem) GenericException - Rozszerzenie klasy Exception o zapis wyjatkow do loga PGException - klasa wyjatku bazy danych Klasy dodatkowo korzystaja z kilku stalych (np. connection string, sciezka do katalogu z cachem itp), ktore trzymam w osobnym pliku -> gdyby ktos chcial przetestowac na zywo dzialanie klasy to trzeba odpowiednie pliki wygenerowac wraz ze stalymi. Najwazniejsze cechy moich klas to: - cachowanie zapytan do pliku tekstowego / odczytywanie zapytan z takiego cachu - system obslugi wyjatkow z zapisem bledow do logow - mozliwosc iterowania wyniku - zastsowany interfejs iteratora Jako ze jestem poczatkujacy prosze o ocene kazdego aspektu, ktory przyjdzie wam do glowy - poczynajac od kodu a na organizacji projektu konczac - kazda rada / wytkniecie bledu mile widziane. Przykladowe zastosowanie
Ten post edytował athabus 15.06.2006, 19:28:22 |
|
|
![]() |
![]()
Post
#2
|
|
Grupa: Zarejestrowani Postów: 352 Pomógł: 0 Dołączył: 22.01.2006 Ostrzeżenie: (0%) ![]() ![]() |
Zrobiłem parę testów na MySQL. Niestety nie korzystam z PostgreSQL więc nie mogłem przetestować Twojej klasy, natomiast testy oparłem na klasie, którą napisał MikeMech.
Jedną rzecz tylko zmieniłem w jego klasie, przeniosłem ją na rozszerzenie mysqli, bo akurat z tego korzystam i nawet nie mam zainstalowanego rozszerzenia mysql. Testy robiłem na win XP, PIV 2.4Ghz, 1GB ram, php 5.1.3, MySQL 5.0.18, Apache 2.0.55 Ustawiłem też priorytet procesów apache i mysql na realtime aby jak najmniejszy był wpływ zewnętrznych czynników. Skoncentrowałem się na pojedyńczym wywołaniu skryptu poprzez narzędzie apache benchmark. Myślałem o zrobieniu testów wywołując kilka zapytań na raz ale w odpowiedzi dostawałem, prawie zawsze jakieś nie udane więc zrezygnowałem. Początek skryptu:
Następnie jest wysyłanych 100 zapytań. Serwer MySQL domyślnie cache'uje zapytania. Tak więc w pierwszym teście zdajemy się na cache mysql a w drugim na cache php: W pierwszym teście wszystkie zapytania idą do serwera mysql:
W drugim korzystam z opcjonalnego cache'owania poprzez metodę QueryCached()
Wszystkie testy przeprowadziłem 10 razy i poniżej podaję średnią wartość. Przeprowadziłem też testy dla dwóch różnych rozmiarów odpowiedzi (40 znaków i ok 20 tysięcy znaków) Dla zapytania zwracającego ok. 40 znaków bez cache'a php: 0.283 sek z cache'em php: 0.311 sek Dla zapytania zwracającego ok. 20 000 znaków bez cache'a php: 0.42 sek z cache'em php: 0.45 sek Pierwsza refleksja jest taka, że jednak próba cache'owania przez php wychodzi nieco słabiej niż zdawanie się na natywny cache mysql. Jednak trzeba wziąść parę dodatkowych czynników, po pierwsze skrypt MikeMech cache'uje zapytania MySQL poprzez zapis i odczyt danych do pliku na dysk, co z zasady skazuje skrypt na nie najlepszą wydajność. Na pewno te wyniki byłyby znacznie lepsze i całkiem możliwe, żeby przegoniły mysql'owy cache gdyby dane były cache'owane do pamięci ram ale wtedy musimy albo zastosować zewnętrzne rozszerzenie jak mmcache.. albo zrezygnować z myśli o cache'owaniu zapytań pomiędzy wywołaniami. Twoje wyniki athabus tłumaczę tym, że w Postgre nie ma opcji cache'owania zapytań albo miałeś cache'owanie poprzez Postgre wyłączone (?) Odnośnie połączenia z bazą, to można sprytnie zrobić aby połączenie z MySQL następowało dopiero tuż przed wykonaniem pierwszego zapytania, wtedy jeśli przy przejściu algorytmu nie jest wywoływane żadne zapytanie mysql, w ogóle serwer mysql nie jest dotykany. Jednak aby to osiągnąć trzeba skorzystać z dóbr magicznej funkcji __autoload(). Przykładowo, w jednym pliku masz klasę MySQL, która jest sterownikiem wywołujacym zapytania na bazie. W innym pliku masz klasę ProjektDAO, której jedynym zadaniem jest komunikacja z klasą MySQL i przez nią wywoływanie zapytań na potrzeby danego projektu. W pliku, w którym jest definicja klasy ProjektDAO zaraz za tą definicją umieszczasz linijkę kodu, czy wywołujesz funkcję nawiązującą połączenie z bazą danych. W praktyce przy zdaniu się na __autoload() plik z ProjektDAO zostanie wincludowany przy pierwszym wywołaniu do tej klasy.. tak więc jeśli nie wywołujesz żadnych zapytań do ProjektDAO połączenie z bazą w ogóle nie następuje.. natomiast jak wywołujesz zapytanie do ProjektDAO automatycznie przy includowaniu pliku jest nawiązywane połączenie. Ten post edytował mariuszn3 16.06.2006, 23:50:04 |
|
|
![]() ![]() |
![]() |
Aktualny czas: 4.10.2025 - 22:50 |