Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Czy oplaca sie cachowac zapytania bazy danych
Forum PHP.pl > Forum > PHP
vadergb
Mam takie pytanie

Oplaca sie cachowac zapytania z bazy danych jesli cachuje dany box.


np.
cachuje calego newsa(ilosc komentarzy, autora, kategorie, tagi etc.)

Tak na chlopski rozum nie oplaca sie cachowac zapytan i tego boxu (wtedy najpierw bedziemy musiel cachowac zapytanie a potem dany box - co za tym idzie bezsensu robimy cachowanie bazy).

Jesli moje myslenie jest dobre i w tym przypadku nie oplaca sie cachowac zapytania to mozna zrobic tak z wszystkim tj.

komentarze (nie cachujemy zapytan tylko caly box z komentarzami tj. autor, + dodatkowae opcje(np ilosc znajomych etc))

Patrzac na to cachowanie bazy danych jest zbedne(biorac pod uwage ze np. mysql ma system wlasny cachujacy)...

Jesli sie myle prosze o napisanie co jest bardziej oplacalne(mowimy o tym aby strona chodzila szybciej i mowimy tu o stronie gdzie dziennie jest grubo ponad 100 tys odslon ! )
erix
Cytat
Tak na chlopski rozum nie oplaca sie cachowac zapytan i tego boxu (wtedy najpierw bedziemy musiel cachowac zapytanie a potem dany box - co za tym idzie bezsensu robimy cachowanie bazy).

Jeden cache więcej = N*zapytanie mniej.

N = liczba użytkowników otwierających stronę jednocześnie.
vadergb
Ale zauwaz ze jak mamy zapisany caly news w cache - to odczytujemy jego a nie zapytania z bazy.

Chodzi o to ze cachujemy sam box z np. newsem a nie zapytania.
erix
No to tym lepiej. ;]

Cytat
biorac pod uwage ze np. mysql ma system wlasny cachujacy

To powiedz, dlaczego każda porządna biblioteka ma system cache? tongue.gif
vadergb
Jesli mowisz o frameworkach to one sa zlym wyjsciem dla duzych stron.

Mowimy o przypadku gdy cachujemy calego boxa z newsami - czy wtedy cachowanie bazy cos daje?

Albo inaczej

co bardziej sie oplaca robic np pobierajac newsa:

1. cachowac zapytanie z bazy
2. cachowac calego newsa (z kategoriami,autorem etc)
3. cachowac zapytanie z bazy + cachowac calego newsa
erix
Cytat
Mowimy o przypadku gdy cachujemy calego boxa z newsami - czy wtedy cachowanie bazy cos daje?

Ja robię podobnie na blogu - mam sidebar z kilkoma zapytaniami. Ale nie zmienia się on za często, więc robię cache na godzinę ważności. Zwykłe ob_start" title="Zobacz w manualu PHP" target="_manual z zapisywaniem do pliku. I baza jest odpytywana tylko wtedy, jeśli nie ma cache.

Cytat
Jesli mowisz o frameworkach to one sa zlym wyjsciem dla duzych stron.

Teoretycznie tak, praktycznie - zdziwiłbyś się, ile stron napędzają frameworki.

Cytat
2. cachowac calego newsa (z kategoriami,autorem etc)

Tak, jak napisałem wcześniej - samo zbuforowanie wyniku zapytania znacznie zmniejszy zużycie na zasoby. A maksymalne efekty osiągniesz zapisując cały wygenerowany blok.
vadergb
Czyli jesli chce zrobic najbardziej wydajna strone to:

1. powineineme zrezygnowac z cache zapytan do bazy na rzecz cache boxow(w klasie ktora pobiera zapytanie nawet nie umieszczac opcji cachowania zapytan - czy moze do czegos sie to przyda?)


Tak ostatnio zastanawialem czy oplaca sie korzystac z klasy PDO dla 100 wywolan zapytania SELECT id_base,time FROM time_base limit 1

zwykle 0.012507927299726
class PDO 0.013354476379311
classa extends PDO(czyli mozna tu dodac cachowanie, debugowanie i wszytko) 0.016115679599271

classa extends PDO - klasa ktora dziedziczy PDO - klasa PDO + dodatkowe funkcje

jak widac zwykle zapytanie jest najszybsze. Najgorsza wydajnosc ma klasa ktora dzieczy pdo . Tak sie zastanawiam czy oplaca sie napisac swoja klase, korzystac ze zwyklego mysql_query, napisac swoja klase do klasy pdo, korzystac tylko z pdo...

Dodam ze chodzi mi glownie o wydajnosc jako ze strona ktora mam( i chce przerobic ) ma ponad 100 tys odslon dziennie - a planuje rozbudowe i ta ilosc moze sie zwiekszyc kilkakrotnie.

pozdrawiam
phpion
Cytat(vadergb @ 10.06.2009, 22:06:46 ) *
zwykle 0.012507927299726
class PDO 0.013354476379311
classa extends PDO(czyli mozna tu dodac cachowanie, debugowanie i wszytko) 0.016115679599271

No właśnie. Warto korzystać ze zwykłych funkcji? Moim zdaniem nie. Różnice są na tyle niewielkie, że zdecydowanie lepiej wybrać PDO (lub jego rozszerzenie wedle potrzeb).
vadergb
Niby sa niewielki roznice ale gdy jest 1000 osob online to troche to daje.


JEszcze mam jedno pytanie. Z tego co wiadomo nie powinno sie robic zapytan w petli... wszystko fajnie jak jest news i mamy pobrac autora w jednym zapytaniu to pobierzemy. Ba nawet gdy mamy ilosc komentarzy to tez to pobierzemy.

A gdy nam sie trafi ze musimy pobrac kategorie ktore sa zapisane w innej tablicy i zeby odczytac je wszystkie trzeba wykonac while

czyli

  1. <?php
  2. while($news=costam){
  3.  
  4. while($cat where id_news=$news[id_news]){
  5. }
  6.  
  7. }
  8. ?>


Tak wykonamy robiac petle w petli a gdy chcemy tego uniknac? To jak to mozna optymalnie pobrac?


Z tego co sie orientuje przy duzych projektach(duzo uzytkownikow):
- nie powinno sie korzystac z frameworkow(po co komu xxx klas ktore pozeraja cenny czas)
- teoretycznie kod strukturalny jest szybszy od class

Ja robiac duzy projekt myslalem o zastosowaniu:
-modelu MVC i najprostszych do tego klas(wszystko proste zeby duzego obciazenia nie bylo).
-cachowanie boxow
-klase na sesje, klase na autoryzacje(dostep do danych podstron).
-PDO + klasa dziedziczaca do niej.




Zastanawialem sie takze ostatnio nad zastosowaniem do PDO klasy Open Power Driver(http://www.eioba.pl/a70003/biblioteka_pdo_bazy_danych_podstawy_php - tu na dole jest opisana).

JEdnak po testach przy pobieraniu zapytania nie cachujac za pomoc klasy OPD i PDO wynik byl o wiele bardziej zadawalajacy na korzysc PDO.
Fifi209
Jeżeli chcesz mieć szybko pisz własne biblioteki w C/C++ (nie pamiętam jaki to język był), będzie o wiele szybciej niż kod strukturalny w php.
erix
Cytat
Różnice są na tyle niewielkie, że zdecydowanie lepiej wybrać PDO (lub jego rozszerzenie wedle potrzeb).

Na pewno? Ja nie jestem tego taki pewien: http://dealnews.com/developers/php-mysql.html

Cytat
A gdy nam sie trafi ze musimy pobrac kategorie ktore sa zapisane w innej tablicy i zeby odczytac je wszystkie trzeba wykonac while


Cytat
Tak wykonamy robiac petle w petli a gdy chcemy tego uniknac? To jak to mozna optymalnie pobrac?

Przecież jak masz napisaną relację jeden - do-wielu (news - news2cat - cat) wszystko leci jednym zapytaniem i po prostu wyciągasz.

Cytat
- teoretycznie kod strukturalny jest szybszy od class

Ale dużo ciężej coś poprawić/zarządzać. Jak zmienisz np. front-end do bazy, to wymieniasz tylko klasę, a nie łapiesz dziesiątki funkcji. O problemach z widocznością/zasięgiem/porządkiem wśród zmiennych nie wspomnę.

Cytat
- nie powinno sie korzystac z frameworkow(po co komu xxx klas ktore pozeraja cenny czas)

Zależy. Przy większych projektach tworzy się dedykowane rozwiązania.

Cytat
-cachowanie boxow

A gdyby tak całych stron? Powiedzmy - na tylko minutę, przy wielu użytkownikach połączonych jednocześnie zmniejszy diametralnie obciążenie (pomijam części wymagające logowania, etc). Zobacz, jak działa np. WP-Supercache.

Cytat
-klase na sesje, klase na autoryzacje(dostep do danych podstron).

Nie lepiej ACL zintegrowany z sesją?

Cytat
-PDO + klasa dziedziczaca do niej.

Patrz, link wyżej.

PS. O shm/akceleratorach przypominać chyba nie muszę?
vadergb
Cytat
Cytat
Różnice są na tyle niewielkie, że zdecydowanie lepiej wybrać PDO (lub jego rozszerzenie wedle potrzeb).
Na pewno? Ja nie jestem tego taki pewien: http://dealnews.com/developers/php-mysql.html


Czyli powinienem sobie odpuscic PDO? i napisac wlasna klase? Czy skorzystac z mysqli + dopisac ew. klase dziedziczna

Cytat
A gdyby tak całych stron? Powiedzmy - na tylko minutę, przy wielu użytkownikach połączonych jednocześnie zmniejszy diametralnie obciążenie (pomijam części wymagające logowania, etc). Zobacz, jak działa np. WP-Supercache.

Hmm przypuscmy podczas wyswietlania newsa (przypuscmy) mamy 3 boxy
[news] => zadko sie zmienia - cachujemy jako box
[komentarze] => Zmieniaja sie czesciej niz news - cachujemy jako box
[podobne newsy] => Zmieniaja sie (gdy pojawia sie jakis news z podanej kategorii) - cachujemy boxem
Gdybysmy cachowali cala strone to po zabawie z ktoryms komentem, newsem etc musimy cachowac od nowa. Chcialbym takze zaznaczyc ze te boxy bylyby cachowane do czasu edycji ktoregos elementu(nie ze wzgledu na czas).



Cytat
Nie lepiej ACL zintegrowany z sesją?

O to mi chodzilo.
erix
Cytat
Czyli powinienem sobie odpuscic PDO? i napisac wlasna klase? Czy skorzystac z mysqli + dopisac ew. klase dziedziczna

Właśnie. Osobiście, z PDO korzystam wtedy, gdy muszę (SQLite3) albo przy dosłownie malutkim projekcie, w którym trzeba coś szybko naskrobać. Coś większego - własny wrapper.

Cytat
Gdybysmy cachowali cala strone to po zabawie z ktoryms komentem, newsem etc musimy cachowac od nowa. Chcialbym takze zaznaczyc ze te boxy bylyby cachowane do czasu edycji ktoregos elementu(nie ze wzgledu na czas).

I ok, rozsądnie. :]

Ale wiesz - przy większym obciążeniu stosuje się wtedy demony, które są zoptymalizowane do wywołań statycznych (np. YAWS w Erlangu, Nginx; YAWS jest potężny winksmiley.jpg). Wtedy cache całości ma sens.
vadergb
co do
Cytat
PS. O shm/akceleratorach przypominać chyba nie muszę?


To sa sprawy zalezne od serwera. Mi chodzi o to co zrobic od strony skryptu(programisty) aby wszystko smigalo dobrze
erix
Jeśli chodzi o shm, to i od programisty zależy... (konkretniej od sterownika cache'ującego)
vadergb
Cytat
Cytat
Tak wykonamy robiac petle w petli a gdy chcemy tego uniknac? To jak to mozna optymalnie pobrac?
Przecież jak masz napisaną relację jeden - do-wielu (news - news2cat - cat) wszystko leci jednym zapytaniem i po prostu wyciągasz.


Tu mamy relacje wielu do wielu chyba

1 tabela newsy: [id_news,tytul]
2 tabela kategorie [id_cat,nazwa]
3 tabela news_cat [id_news,id_cat]

mamy 2 newsy
1 => [1,pierwszy news]
2 => [2, drugi news]
mamy 2 kategorie
1=> [1, pierwza kategoraia]
2=> [2, druga kategoria]
rekordy w news_cat:
1=> [1,1](1 news do 1 kategorii)
2=> [1,2](1 news do 2 kategorii)
3=> [2,1](2 news do 1 kategorii)

czyli musimy zrobic
  1. <?php
  2. $query = "SELECT id_news, tytul FROM newsy limit 5";
  3.        $result = mysql_query ( $query );
  4.        while ( ($line = mysql_fetch_array ( $result )) ) {
  5.  
  6. echo 'To jest tytul: '.$line[tytul].'<br />';
  7.    $query1 = "SELECT kategorie.nazwa FROM news_cat, kategorie where news_cat='$line[id_news]' and news_cat.id_cat=kategorie.id_cat";
  8.        $result1 = mysql_query ( $query1 );
  9. echo 'To sa kategorie:';
  10.        while ( ($line1 = mysql_fetch_array ( $result1 )) ) {
  11. echo '$line1[nazwa],';
  12.  
  13.  
  14.        }
  15. ?>


Kod napisany na szybko nie wiem czy dziala chodzilo o to zeby pokazac o co mi chodzi.

takie cos wyswietli nam
1 box:
To jest tytul: pierwszy news
To sa kategorie: Pierwsza kategoria, druga kategoria,
2 box:
To jest tytul: drugi news
To sa kategorie: Pierwsza kategoria

Jak wyswietlic cos takiego bez uzycia petli w petli jak pokazalem to u gory ?
phpion
Cytat(vadergb @ 11.06.2009, 12:37:13 ) *
Jak wyswietlic cos takiego bez uzycia petli w petli jak pokazalem to u gory ?

Ja tego typu sprawy rozwiązuję 2 zapytaniami:

Pierwsze:
  1. SELECT id_news, tytul FROM newsy LIMIT 5;

Drugie:
  1. SELECT news_cat, kategorie.nazwa FROM news_cat, kategorie WHERE news_cat IN (SELECT id_news FROM newsy LIMIT 5) AND news_cat.id_cat=kategorie.id_cat;

Potem tylko odpowiednie obrobienie tego w PHP (utworzenie odpowiedniej tablicy) i masz wszystko co trzeba.

Jeżeli Twoja wersja MySQL nie obsługuje LIMITu w podzapytaniu lub chciałbyś się po prostu pozbyć podzapytania to możesz w PHP pobrać wszystkie wyciągnięte id z zapytania pierwszego, przypisać je do tablicy no i potem w PHP:
  1. <?php
  2. mysql_query('SELECT news_cat, kategorie.nazwa FROM news_cat, kategorie WHERE news_cat IN ('.implode(', ', $tab).') AND news_cat.id_cat=kategorie.id_cat');
  3. ?>
vadergb
Zrobilem cos takiego:
  1. <?php
  2. $query = "SELECT news . * , GROUP_CONCAT( DISTINCT game ORDER BY game DESC  SEPARATOR  ', ' ) as dupa
  3.         FROM news LEFT JOIN news_cat ON news_cat.id_news = news.id_news
  4.          LEFT JOIN games ON news_cat.id_cat = games.id_game GROUP BY id_news LIMIT 0 , 30";
  5.        $result = mysql_query ( $query );
  6.        while ( ($line = mysql_fetch_array ( $result )) ) {
  7.        }
  8. ?>



vs
  1. <?php
  2. $query = "SELECT * from news";
  3.        $result = mysql_query ( $query );
  4.        while ( ($line = mysql_fetch_array ( $result )) ) {
  5.            
  6.    $query22 = "SELECT games.game from news_cat,games where news_cat.id_news=".$line['id_news']." and news_cat.id_cat=games.id_game";
  7.        $result22 = mysql_query ( $query22 );
  8.        while ( ($line22 = mysql_fetch_array ( $result22 )) ){
  9.        }
  10.        }
  11. ?>


przy petli 100x pobran:

1 sposob 0.24362802505493
2 sposob 0.35362802505493

Baza liczy okolo 20-30 newsow(malo), kategori(games) - liczy okolo 20, a a news_cat liczy tez okolo 20


Wszystko fajnie... ale co jak chcemy pokazac inaczej te dane niz nazwa1, nazwa2, nazwa3 ?

jesli np chcemy zrobic z tego <a href="link do newsow tylko danej kategori>nazwa1</a>,<a href="link do newsow tylko danej kategori>nazwa2</a>?

Mamy pobrac w nastepne pole(albo to samo id)? i bawic sie tym? utworzyc z tego tablice a potem wyswietlic? (Wszystko to kosztuje czas)...


Znalazlem jeszcze jeden sposob
  1. <?php
  2. $query = "SELECT * from news order by id_news";
  3.        $result = mysql_query ( $query );
  4.        
  5.       $wynik = array();
  6.        while ( ($line = mysql_fetch_array ( $result )) ) {
  7.               $wynik[$line['id_news']] = array( // 1
  8.                                'id_news' => $line['id_news'],
  9.                                'title' => $line['title'],
  10.                                'cat' => array() // 2            
  11.                        );
  12.        }
  13.    $query22 = "SELECT news_cat.id_news,games.game,games.id_game from news_cat,games where news_cat.id_cat=games.id_game";
  14.        $result22 = mysql_query ( $query22 );
  15.        while ( ($line22 = mysql_fetch_array ( $result22 )) ){
  16.             $wynik[$line22['id_news']]['cat'][] = array( // 4
  17.                                'game' => $line22['game'],
  18.                                'id_game' => $line22['id_game']                
  19.                        );
  20.        }
  21.         $i=0;  
  22.     foreach($wynik as &$news_show)
  23.                {
  24.                    $i++;
  25.                        echo '<h3>'.$i.'. '.$news_show['title'].' ('.$news_show['id_news'].')</h3>';
  26.                        foreach($news_show['cat'] as &$kategoria)
  27.                        {
  28.                                echo '<p><i>'.$kategoria['game'].'</i>
  29.                                (Wyd. '.$kategoria['id_game'].')</p>';                  
  30.                        }
  31.                }
  32.    }
  33. ?>


Jesli chodzi o czas wykonania dla 100 pobran to jest on wiekszy od 1 sposob z postu wyzej i mniejszy od 2 sposob z postu wyzej.

Tylko ze tych kategori nie ma duzo (okolo 20)... a co jak ich bedzie 200 ? Ten sposob wtedy sie mija z celem...



Jaka jest najbardziej optymalna droga?
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.