Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Czy opłaca się utrzymywać połączenie z bazą?
Forum PHP.pl > Forum > Bazy danych > MySQL
SpokoJny_
Witam!

Mam taki dylemat(prawdopodobnie z powodu mojej niewiedzy):
Czy w ciągu jednego przebiegu skryptu lepszym rozwiązaniem jest wywoływać funkcje mysql aby połączyć się z baza przy okazji wystąpienia każdej potrzeby pobrania/zapisu danych, a następnie połączenie zamykać - czy też uchwyt do połączenia przechować w jakiejś zmiennej(np. polu klasy)?

Myślę, że pomogło by mi porównanie - proste zapytanie vs łączenie.

Pozdrawiam i z góry dziękuję za odpowiedzi.
lDoran
Najwięcej zasobów jest używanych przy połączeniu z bazą danych z tego co się orientuję, dlatego warto trzymać uchwyt.
vokiel
Wygenerowanie strony to jest jedna całość, i tak należy traktować połączenie z bazą. Jest żądanie strony, zatem dla tego żądania jest ustanawiane połączenie, zapisywane do zmiennej i wykorzystywane tyle razy, ile zachodzi potrzeba.
mkozak
Twój pomysł jest zły. To tylko spowoduje spadek wydajności i to w każdym przypadku kiedy używasz chociaż 2 zapytań.

Cytat(lDoran @ 27.08.2010, 18:03:39 ) *
Najwięcej zasobów jest używanych przy połączeniu z bazą danych z tego co się orientuję, dlatego warto trzymać uchwyt.



W Oraclach i innych tam wymysłach to rzeczywiście ma znaczenie.
Mysql jest prostą i lekką bazą, więc tutaj nie należy sie tak przejmować podtrzymywaniem połączenia.
Kilka razy spotkałem się z tak kiepskim pomysłem jak nadużywanie mysql_pconnect (persistent connection), czyli stałe połączenia.
Ktoś sobie wymyślił, że oszczędzi na wydajności pozostawiając otwarte połączenia, a w efekcie wyczerpywała się cała pula dostępnych połączeń i system stawał dęba, aż do restartu bazy.
SpokoJny_
Gdy moja strona nie przekracza 15 klas, wtedy warto?
A np jak to jest rowiązane w większych projektach np profesjonalnych forach?

TESTY PRAKTYCZNE

Myślę, że najlepiej jest po prostu sprawdzić winksmiley.jpg
Będziemy liczyć stosunek: czas połączenia z bazą/czas wykonania zapytania.
W obu przypadkach użyta jest funkcja microtime oraz round z takimi samymi parametrami, tak więc przy liczeniu stosunku nie ma to znaczenia.
W bazie 'sm' znajduje się tabela 'admins':
adminid(tinyint) - login(char(32)) - password(char(32))
oraz 10 rekordów

---------- Sytuacja idealna (1user) ------------
Kod ustalający ile trwa łączenie w sytuacji idealnej (1 user, serer na jednym komputerze z klientem):
  1. function connect(){
  2. $con = new mysqli('localhost', 'root', '', 'sm');
  3.  
  4. }
  5.  
  6. $start = microtime();
  7. connect();
  8. echo 'czas polaczenia'. round(microtime()-$start, 8);
  9. ?>

Kod ustalający ile trwa czas zapytania:
  1. <?php
  2. $con = new mysqli('localhost', 'root', '', 'sm');
  3. $q =
  4. "select * from admins";
  5.  
  6. $start = microtime();
  7. $con->query($q);
  8. echo 'czas zapytania'. round(microtime()-$start, 8);
  9. ?>

Wyniki(średnia "na oko")
połączenie: 0,001
zapytanie: 0,0002
połączenie/zapytania = 5

---------- Sytuacja idealna - kod symulujący pracę między zapytaniami ----------

Kod z wieloma połączeniami
  1. <?php
  2. function delay(){
  3. $a= 0;
  4. $b =0;
  5. $c =0;
  6. for($i=0; $i<=50; $i++, $a++, $b+=2){
  7. $c = $a + $b;
  8. }
  9. }
  10. function query(){
  11. $con = new mysqli('localhost', 'root', '', 'sm');
  12. $q =
  13. "select * from admins";
  14. $con->query($q);
  15. $con->close();
  16. }
  17. function action(){
  18. for($i=0; $i<5; $i++){
  19. query();
  20. delay();
  21. }
  22. }
  23. $start = microtime();
  24. action();
  25. echo 'czas zapytania'. round(microtime()-$start, 8);
  26. ?>


Kod z ciągłym połączeniem:
  1. <?php
  2.  
  3. function delay(){
  4. $a= 0;
  5. $b =0;
  6. $c =0;
  7. for($i=0; $i<=50; $i++, $a++, $b+=2){
  8. $c = $a + $b;
  9. }
  10. }
  11. function query($con){
  12.  
  13. $q =
  14. "select * from admins";
  15. $con->query($q);
  16.  
  17. }
  18. function action(&$con){
  19. for($i=0; $i<5; $i++){
  20. query($con);
  21. delay();
  22. }
  23. }
  24. $start = microtime();
  25. $con = new mysqli('localhost', 'root', '', 'sm');
  26. action($con);
  27. echo 'czas zapytania'. round(microtime()-$start, 8);
  28. ?>
  29.  


Wyniki:

Ciągłe utrzymywanie w znacznej większości przypadków nieznacznie szybsze od przerywanego.

Podsumowanie
Ponowne łączenie kosztuje nieznaczne ilości czasu, jednak przy małych odstępach czasu między kolejnymi zapytaniami warto połączenie utrzymać.
Przy dużej liczbie zapytań łączenie i zamykanie połączenia przy każdym zapytaniu jest już nieładną praktyką i nie sprzyja wydajności.

Ktoś może się pokusić o przeprowadzenie innych testów, lub sprawdzenie wyników. Myślę, że mogą się nawet znacznie różnić.

Wiem, że nie odkryłem tutaj ameryki, ale może ktoś wpisując w google "czy podtrzymywać połączenie z bazą" będzie miał jaśniejszy obraz sytuacji.
Można też po prostu wykonać testy praktyczne swojego skryptu.

Pozdrawiam - mam nadzieje, że komuś to pomogło.
cojack
Błędne testowanie, używanie global spowalnia aplikację, global jest jak najzwyklejszy żółw.
SpokoJny_
Bardzo dobrze, że zwróciłeś na to uwagę.
Poprawiłem kod, a także edytowałem część we wnioskach.
cojack
Wyniku nie podałeś biggrin.gif

@edit
a pozatym dodaj sobie true jako argument funkcji mictrotime, będziesz miał dokładniejszy wynik.
Pilsener
Połączenie powinno być nawiązane wtedy, gdy jest wymagane (przy pierwszym zapytaniu do bazy) i ze względu na małe zużycie zasobów utrzymywane aż do zakończenia się skryptu. Pod obciążeniem przecież zapytania lecą do bazy non-stop, nie opłaca się połączenia zamykać, a w wypadku braku obciążenia w ogóle nie ma dyskusji.

Jeśli używamy nawet wielu baz mysql nie powinniśmy mieć problemu, przy innych bazach się nie wypowiem, bo np. PHP z Oraclem nie łączyłem.
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.