Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [php][mysql] Optymalizacja zapytania
Forum PHP.pl > Forum > Przedszkole
Optim
Witam.

Mam pewną bazę danych w której sa dwie tabele - jedna z tabel ma okolo 400000 rekordow, druga trochę ponad 1 000 000 rekordów. Dane są tekstowe.

Wyswietlam to na stronie w następujacy sposób
  1. <?php
  2.  
  3. db_open();
  4.  
  5.  $count=500;
  6.  $offset=0;
  7.  
  8.  $wynik = mysql_query("SELECT * FROM `relayreport`")
  9.  or die('Błąd zapytania');
  10.  
  11.  $ile = mysql_num_rows($wynik); 
  12.  $r = $ile;
  13.  if(isset($_GET['count']))$count = $_GET['count'];
  14.  if(isset($_GET['offset']))$offset = $count*$_GET['offset']; //numer strony
  15.  
  16.  $pages = ceil($r/$count);
  17.  
  18.  
  19. echo '<h4 class="roboczy">Przegląd tabeli "<b>relayreport</b> rekordów w bazie ('.$ile.')"</h4>' . "r\n";
  20.  
  21.  
  22.  $sql = "Select * from `relayreport` Limit $offset, $count ";
  23.  $result = mysql_query($sql);
  24.  
  25.  
  26.  for($i=0;$i<$pages;$i++){
  27.  
  28.  if($i*$count==$offset){
  29.  
  30. echo ' <p class="paginator_check">'.$i.' </p>';
  31.  }else{
  32.  
  33. echo '<a href="index.php?pokaz=adresy_relay&count='.$count.'&offset='.$i.'"><p class="paginator"> '.$i.' </p></a>';
  34.  }
  35.  }
  36.  
  37. if(mysql_num_rows($wynik) > 0) {
  38.  
  39. echo "<table>" . "r\n";
  40. //echo "<tr>";
  41. echo "<th><p>nr</p></th>" . "r\n";
  42. echo "<th><p>relay_ip</p></th>" . "r\n";
  43. echo "<th><p>wygasa</p></th>" . "r\n";
  44. echo "<th><p>utworzono</p></th>" . "r\n";
  45. echo "<th><p>czas blokowania</p></th>" . "r\n";
  46. echo "<th><p>blokowano</p></th>" . "r\n";
  47. echo "<th><p>przepuszczono</p></th>" . "r\n";
  48. echo "<th><p>przerwano</p></th>" . "r\n";
  49.  
  50.  
  51.  while($r=mysql_fetch_array($result))
  52.  
  53. {
  54. echo "<tr>" . "r\n";
  55. echo "<td><p>".$r['id']."</p></td>" . "r\n";
  56. echo "<td class=\"centrowany_wynik\"><p>".$r['relay_ip']."</p></td>" . "r\n";
  57. echo "<td><p>".$r['record_expires']."</p></td>" . "r\n";
  58. echo "<td><p>".$r['create_time']."</p></td>" . "r\n";
  59. echo "<td><p>".$r['block_expires']."</p></td>" . "r\n";
  60. echo "<td class=\"centrowany_wynik\"><p>".$r['blocked_count']."</p></td>" . "r\n";
  61. echo "<td class=\"centrowany_wynik\"><p>".$r['passed_count']."</p></td>" . "r\n";
  62. echo "<td class=\"centrowany_wynik\"><p>".$r['aborted_count']."</p></td>" . "r\n";
  63. echo "</tr>" . "r\n";
  64. }
  65. echo "</table>" . "r\n";
  66. }
  67.  
  68. db_close();
  69.  
  70. ?>



Aktualnie dla 400 000 rekordów wyświetlanie to okolo 42 s. czyli dużo. Serwer nie jest demonem prędkości ale jednak wyświetlając tą tabelę w phpmyadminie przy domyślnym limicie 30 rekordów na stronę, radzi sobie on o wiele lepiej niż moj skrypt smile.gif
Działa to prawidłowo ale woolno. czy mogę w jakiś sposób zoptymalizować zapytania do bazy żeby przyspieszyć wyświetlanie strony?

Pozdrawiam
Kowalikus
niepotrzebnie leci pierwsze zapytanie poczytaj o SELECT SQL_CALC_FOUND_ROWS i zamiast gwiazdki wypisz pola jakie chcesz wyciągnąć z zaptytania w 2 zapytaniu.
kszychu
Do zliczenia ilości rekordów użyj SELECT COUNT(*) as ilosc_rekordow .....
MMX3
rysiu tu nie ma nic do optymalizowania...
dysk nie jest wstanie wczytać tylu danych... Albo upstream za słaby
Klauzli where nie ma nawet więc gdzie tu optymalizacja. Sprzęt złomowaty.

W PHP solmag 1#2008 jest coś na temat optymalizacji SQL. Ale takiej gdzie da się cokolwiek optymalizować.

Fakt COUNT ma tylko sens tutaj.

Załóż indeksy na polu po ktorym się sortuje. ewentualnie...
kszychu
Cytat(MMX3 @ 18.02.2008, 16:22:44 ) *
rysiu tu nie ma nic do optymalizowania...

A jednak smile.gif Jakbyś przyjrzał się lepiej, zobaczyłbyś, że ma jedno bezsensowne zapytanie, zajmujące duuuuużo czasu.
MMX3
no tak count tylko smile.gif. Ja miałem 72 s generowania strony kiedyś smile.gif 2000 userów i z 10000 postów.... a wszystko przez brak indeksu na polu username które było relacją z postami smile.gif. Kod nie mój był tylko kumpla z pracy ale udało isę naprawić smile.gif


A zapytanie wyglądało tak

SELECT * FROM messages WHERE username NOT IN (select usr_id from blocked where ....).... i tak 6 razy smile.gif
Optim
Witam.
Dziękuję za ekspresowe podpowiedzi rozwiązania problemu.
Faktycznie Count dał rade i teraz wyświetlenie zajmuje czas podobny do phpmyadmina smile.gif
pozdrawiam serdecznie
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.