2009-03-23 11 views
6

Mam aplikację webową php, w której pewne dane zmieniają się co tydzień, ale są często czytane.Najlepsza technika buforowania wyników z zapytań, które zmieniają się rzadko

Kwerendy SQL, które pobierają dane i kod php dla danych wyjściowych html, są dość złożone. Istnieje wiele powiązań tabel i liczne obliczenia - ale skutkują one dość prostą tabelą html. Użytkownicy są zgrupowani, a tabela jest taka sama dla każdej grupy w każdym tygodniu, ale inna dla różnych grup. Mogłabym mieć setki tabel dla tysięcy użytkowników.

Ze względów wydajnościowych chciałbym buforować te dane. Zamiast uruchamiać te zapytania i obliczenia za każdym razem, gdy ktoś trafi na stronę, chcę uruchomić cotygodniowy proces generowania tabeli dla każdej grupy, dając mi prostą lekturę, gdy jest to wymagane.

Chciałbym wiedzieć, jakich technik użyłeś z powodzeniem lub bezskutecznie, aby osiągnąć coś takiego?

Opcje widzę to:

  • Przechowywanie wynik HTML obliczeń w tabeli MySQL, zidentyfikowane przez grupy użytkowników
  • przechowywania danych wynikowych w tabeli MySQL, zidentyfikowane przez grupy użytkowników (trudne jak nie ma ustalonej liczby elementów danych)
  • Buforowanie wyjścia strona w plikach statycznych

Wszelkie inne propozycje są mile widziane!

Odpowiedz

4

Są rzeczywiście kilka opcji:

  • Wstępne renderowanie stron na tydzień, a potem im służyć „statycznie”.
  • Użyj pamięci podręcznej (np. Squid), aby buforować takie odpowiedzi na zasadzie pierwszej szansy przez tydzień. Na przykład można skonfigurować zasady buforowania, aby żądania przechodzące do określonej strony (np. Bardzo_long.php? ...) były buforowane oddzielnie od reszty witryny.
  • Upewnij się, że włączasz buforowanie bazy danych. MySQL posiada własne buforowanie i możesz je dostroić, aby powtarzające się długie zapytania nie były ponownie obliczane.
+0

Kilka świetnych sugestii, dzięki. – Damovisa

+0

Dobra lista sugestii tutaj. Pamiętaj, że buforowanie zapytań MySQL nie jest kompletną poprawką - wszystko - ma zalety i wady (może pogorszyć sytuację w przypadku często aktualizowanych danych). Jak sugeruje Assaf, jest to tylko jedna z wielu opcji. – thomasrutter

2

przede wszystkim profil. sprawdź, czy te zapytania naprawdę pochłaniają znaczną ilość czasu. może pamięci podręczne wyników MySQL już wykonały pracę za Ciebie.

jeśli naprawdę zużywają zasoby, to powinienem stworzyć tabelę z wyliczonymi wynikami, a także procedurę wymagającą zarządzania, która zostanie wywołana podczas zmiany danych. te częste odczyty powinny dotyczyć tylko danych z wcześniejszych obliczeń, bez konieczności sprawdzania, czy są nadal aktualne.

po prostu dodać kilka haczyków do procedur, które modyfikują podstawowe dane lub wyzwalacze bazy danych, jeśli możesz, byłyby wykonywane niezbyt często (co tydzień?) I mogą zająć dużo czasu, aby wygenerować jakiekolwiek wyniki.

+0

Myślę, że po raz pierwszy widziałem, gdzie pytanie ma cztery odpowiedzi i wszystkie są dobre (wszystkie zasługują na up-vote)! Dobre sugestie tutaj. Konieczność profilowania przed optymalizacją to dobry punkt. – thomasrutter

+0

Prawda - byłem pod wrażeniem! – Damovisa

6

W funkcji wygenerować tabelę, należy to zapisać wynik do pliku na dysku:

/cache/groups/1.txt 
/cache/groups/2.txt 

nie muszą koniecznie prowadzić cotygodniowe zadania wsadowego do niego, gdy wywołanie funkcji do uzyskać dane, sprawdzić, czy pamięć podręczna jest nieaktualna (lub nieistniejąca).Jeśli tak, generuj i buforuj wyniki. Jeśli nie, po prostu zwróć buforowany plik.

function getGroupTable($groupId) { 
    if (cacheIsStale($groupId)) { 
     generateCache($groupId); 
    } 
    return file_get_contents($cacheFile); 
} 

Funkcja cacheIsStale() mógł tylko patrzeć na file's timestamps do testowania świeżości.

+0

Tak już dawno temu rozwiązałem taki problem. –

+0

To dobre rozwiązanie i prawdopodobnie będę go używać. Po prostu interesuje mnie potencjalna (w przyszłości) potrzeba korzystania z generowanych danych, a nie tylko z html. – Damovisa

+0

w takim przypadku możesz prawdopodobnie zapisać wyniki z MySQL w innym, bardziej dostępnym formacie. CSV będzie działał łatwo (funkcja fgetcsv pomaga tutaj), lub możesz nawet umieścić wynik w tablicy, a następnie serializować go. Oczywiście można zrobić dwa pliki pamięci podręcznej: HTML, a także surowe dane. – nickf

2

Wygląda na to, że już większość obejmuje.

Inna opcja, zakładając, że dane w tabeli nie są duże, polega na użyciu memcache do buforowania wyników - prawdopodobnie byłoby to szybsze rozwiązanie, chociaż trzeba sprawdzić wymagania dotyczące pamięci, aby sprawdzić, czy jest to opłacalna opcja.