Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [inne][PHP][MySQL]Cachowanie - kilka pytań praktycznych
Forum PHP.pl > Forum > Przedszkole
Userr
1. Powiedzmy, że chciałbym zcachować informacje, które pojawiają się w profilach użytkowników (przykładowo tych profili będzie 10 000). W każdym profilu będą 3 tabelki, a w każdej z nich po 5 wierszy. Czy wydajniej będzie trzymać informacje z tych tabelek w trzech różnych plikach cache, czy w jednym (i np. rozdzieliłbym informacje z tych tabelek pustą linią (znak ENTER'a) lub jakimś ciągiem znaków np. ##################### i później w PHP już w prosty sposób byłoby rozdzielić to za pomocą explode())?

2. Jeżeli mam w pliku cache informacje składającą się z 100 000 wierszy i chciałbym dodać nowy wiersz, to nadpisuję zawartość całego pliku cache, czy jakoś tylko dodaje na sam koniec nowy wiersz?

3. Dlaczego wczytanie z cache jest szybsze niż zapytanie z relacyjnej bazy danych (nie mówię tu o jakimś bardziej złożonym zapytaniu, które wymaga dodatkowych obliczeń - np. sortowaniu, tylko o najprostszym select - wczytaniu zawartości tabeli)? Relacyjna baza danych jest przechowywana na HDD serwera, a gdzie jest przechowywany plik cache? W jakiejś specjalnej szybkiej (skoro wczytywanie z cache jest szybsze niż z relacyjnej bazy danych) pamięci cache - jakby nazwa wskazywała smile.gif ?
by_ikar
AD1 nie twórz swoich formatów, serializuj dane i je deserializuj. Im mniej odwołań do dysku tym lepiej.
AD2 100k wierszy w pliku? Słabo.
AD3 plik ma tylko jedno odwołanie, relacje są ogólnie "ciężkie". Mówiąc cache, zazwyczaj myśli się o pamięci ram, np redis/memcache. Działają one szybciej niż relacyjne bazy bo: mają płaską strukturę, oraz wszystko trzymają w pamięci ram, do której dostęp jest kilka rzędów szybszy niż do dysku twardego.

Jeżeli zapytanie jest wolne, to albo masz brak indeksów, albo sama struktura bazy jest kiepska. Odczytując dane z pamięci ram będzie szybsze, ale nie w każdym przypadku. Po prostu redis/memcache poradzą sobie w tym przypadku zdecydowanie lepiej niż relacyjna baza danych, bo podchodzą do tematu zupełnie inaczej. Co nie znaczy że powinieneś się w całości przesiąść na redisa/memcache.
Pyton_000
A [p co wrzucać do cache informacje o profilach? Aż tak często będą wyświetlane?

Cache w zależności od metody albo działa na plikach, na BD lub RAM (Redis, Memcached itd).

Cache zawsze musisz odbudować w całości jeśli się coś zmienia (w całości znaczy cały konkretny element a nie wszystkie elementy)
borabora
należałoby zacząć od tego, że dla 10tys userów nie bedziesz potrzebował cache. kolejna sprawa to zapytanie na pewno wywoła się szybciej niż wczytanie pliku, który ma 100000 wierszy, a następnie wygrzebanie odpowiednich wartości.
zobacz na to w ten sposób... wejdź na poszczególne podstrony swojego serwisu i przypatrz się czy masz jakieś boxy w stylu:
-"top 10 uzytkowników"
-"ostatnie komentarze"
-"najnowsze artykuły"
tego typu dane mógłbyś trzymać w plikach
Userr
Cytat(borabora @ 12.03.2017, 16:08:26 ) *
-"top 10 uzytkowników"
-"ostatnie komentarze"
-"najnowsze artykuły"
tego typu dane mógłbyś trzymać w plikach


Czyli ogólnie dane, których jest "mało", a są aktualizowane raz na jakiś czas?

Przykładowo dla "ostatnich komentarzy" - należałoby aktualizować plik gdy dodany zostanie nowy komentarz, czy np. raz na 10 minut przez skrypt wywoływany przez CRON'a?

Cytat(Pyton_000 @ 12.03.2017, 13:26:55 ) *
A [p co wrzucać do cache informacje o profilach? Aż tak często będą wyświetlane?

Cache w zależności od metody albo działa na plikach, na BD lub RAM (Redis, Memcached itd).


Profile będą wyświetlane jak użytkownik (nie musi być zalogowany) wejdzie na profil innego użytkownika - tak jak na forum smile.gif Powiedzmy, że profilów będzie 10 000, a użytkowników odwiedzających stronę dziennie też 10 000 (ogólnie rzecz biorąc, czyli strona główna i wszystkie podstrony), ale ilość odwiedzeń podstron z profilami będzie raczej niewiele, więc chyba rzeczywiście nie ma sensu tego w plikach?

Na stronie będzie taki ranking uczniów wg. ocen (im lepsze oceny, tym wyżej w rankingu). Jest tu jedno ważne założenie - ranking będzie oczywiście widoczny cały czas na stronie, ale będzie aktualizowany tylko raz na dzień (powiedzmy o godzinie 0:00), czyli oceny z danego dnia będą widoczne w rankingu dopiero następnego dnia. Co byście proponowali w takiej sytuacji?

1. Założyć index na pole ocena i w zapytaniu wyświetlającym dodać warunek, żeby wyświetlane były tylko oceny do dnia wczorajszego?

  1. SELECT * FROM oceny WHERE DATA < $dzisiejsza_data ORDER BY ocena


2. Przechowywać ranking w oddzielnej tabeli „ranking”? Widziałbym to w ten sposób, że skrypt uruchamiany przez CRON'a raz na dzień o godzinie 0:00 sortowałby tabelę oceny (pewnie takim samym zapytaniem jak z pkt. 1) i nadpisywał tabelę „ranking” tym wynikiem sortowania (pewnie trzeba by było użyć truncate oraz ponownie dodać wiersze za pomocą insert). I tak posortowaną tabelę „ranking” wyświetlałbym na stronie. Przewaga takiego rozwiązanie nad cache może być taka, że powiedzmy ta tabela będzie miała z czasem 100 000 wierszy, to tak jak wspominaliście – zapytanie dla 100 000 wierszy wywoła się szybciej niż wczytanie pliku ze 100 000 wierzy.

Czy nie jest przypadkiem tak, że zarówno rozwiązanie 1. jaki i 2. będę równie dobre? smile.gif
Pyton_000
Czyli profile można olać. Możesz wrzucać w cache do Redisa i ustawić TTL na np. 5h, ale to i tak nie ma sensu jeśli te dane nie są non stop wyświetlane .

Ad 2. Co będzie zawierał ranking? Imię, nazwisko i średnia ocen? Czy coś więcej? Ja bym to wpakował i tak w cache żeby nie pobierać z BD tego rankingu. Dodatkowo jeśli będzie tam stronicowanie to każdą stronę oddzielnie w cache dzięki temu zaoszczędzisz pamięć dla stron które nie będą wyświetlane.
Ustawiasz sobie że czas życia takiego Cache to 24h i zapominasz. Możesz oczywiście ustawić czas na podstawie wyliczenia tak żeby jak odpalisz np. teraz stronę to czas był do końca dnia czyli 5,5h. Potem jak ktoś np. odpali o 10 rano pierwszy raz to będziesz miał już 14h. Dzięki temu unikniesz starych danych a świeże będziesz miał zawsze w kolejnym dniu.
Userr
Ranking będzie na początek zawierał tylko takie dane: imię, nazwiska, średniej ocen. Jeżeli w przyszłości by się to zmieniło i zawierałby więcej danych w każdym wierszu, czy to by coś zmieniło?

Będzie stronicowanie - na jednej podstronie będzie wyświetlanych 100 wierszy z rankingu. Czyli jeżeli ranking będzie miał 100 000 wierszy, to będzie 1000 podstron po 100 wierszy na każdej podstronie. Czyli warto to zapisać w taki sposób, że zrobię 1000 plików cache i w każdym zapisać 100 wierszy?

Oprócz tego główne rankingu będę będę chciał zrobić rankingi miesięczne - jest tutaj takie samo założenie jak w tym rankingu głównym: "ranking będzie oczywiście widoczny cały czas na stronie, ale będzie aktualizowany tylko raz na dzień (powiedzmy o godzinie 0:00), czyli oceny z danego dnia będą widoczne w rankingu dopiero następnego dnia". Różnice są takie, że po pierwsze będą w nim średnie ocen tylko z miesiąca (po miesiącu ranking miesięczny zostaje zamknięty i otwierany zostaje nowy na nowym miesiąc, a ten dotychczasowy będzie nadal widoczny gdzieś na stronie, tylko przejdzie do archiwalnych rankingów miesięcznych i nie będzie nigdy aktualizowany), a po drugie będzie w nim wyświetlanych tylko 1000 uczniów z najlepszą średnią ocen z tego miesiąca.

Czy w przypadku tych rankingów miesięcznych też warto wrzucić to do cache na 24 godziny (a po upływie miesiąca taki cache nie byłby już nigdy aktualizowany, bo i ranking nie byłby nigdy aktualizowany)? I każdy ranking miesięczny podzielić na 10 plików po 100 wierszy (jak wspomniałem ranking miesięczny będzie miał 1000 pozycji)?
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.