Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [mysql] optymalizacja zapytań
Forum PHP.pl > Forum > Bazy danych > MySQL
wicy
Witam,
Jestem słabo obeznany a wziąłem sobie na kark obsługę pewnego projektu.
Projekt prosty - www + kilka skryptów php + baza sql.
Baza jest nie duża: 2 tabele - jedna 10.000 wierszy, druga 900 wierszy.
Problem zaczął się z przekraczaniem limitów zapytań do bazy, choć zupełnie nie wiem z czego się to bierze, gdyż ogół wizyt na stronie dzinnie nie przekracza 20-30. Serwer jednak blokuje bazę wypluwając komunikat:
1226: User 'xxx' has exceeded the 'max_questions' resource (current value: 600000000)
i baza pada na jakiś czas.
Ponieważ limit zapytań ustawiony jest na konkretną bazę uworzyłem kopię bazy z myślą, żeby sprawdzać przed wykonaniem zapytania wartość
'max_questions' i przy przekroczeniu limitu nie narażać się na zwiechę bazy, ale przekierować zapytania do kopii bazy.
Jak sprawdzić
wartość 'max_questions' przed wykonaniem zapytania do bazy??

$link = mysql_connect('xxxl:3306', $username, $password) or die('Nie można się połączyć: ' . mysql_error());
@mysql_select_db($database) or die("Nie udało się wybrać bazy danych");

$result=mysql_query("SELECT * FROM cmentarz WHERE id = ".$m);



Jedyne rozwiązanie jakie na szybko przyszło mi do głowy, dla zmniejszenia ilości zapytań generowanych do bazy sql, to utworzenie kilku kopii tej samej bazy. Kilka skryptów odwołujących się do bazy odwołuje się teraz do róznych baz - każdy do swojej. Teoretycznie powinno to dla 4 baz zmniejszyć ilość zapytań o 75% dla bazy, ale nie mam pojęcia który ze skryptów generuje największą ilość zapytań.
Da się to jakoś sprawdzić? Czy tylko za pomocą admina powidera??
nevt
nie tędy droga - sytuacja którą opisujesz jednoznacznie wskazuje na jakiś istotny błąd w którymś ze skryptów php - najprawdopodobniej pętla w nieskończoność odwołująca się do bazy... jeżeli nie jesteś autorem serwisu - może być ci ciężko namierzyć ten bład...
ale możesz spróbować tak: załóż w bazie tulu userów ile jest skryptów korzystających z bazy - każdy skrypt zmodyfikuj tak, żeby łączył się z bazą na innym koncie - przy następnej wysypce serwera dostaniesz komunikat który użytkownik (czyli skrypt) powoduje problem - potem wrzuć tu kod tego skryptu i może jakoś wspólnie znajdziemy przyczynę problemu...
misiek08
Można dawać if(!$result = mysql_query[..]){die("Skrypt pobierzdane.php");} w każdym skrypcie zmieniając treść i zobaczyć co wyjdzie.
wicy
Tak też zrobiłem. Dla 5 skryptów korzystających z bazy - 5 baz. Każdy korzysta ze swojej. Wysypuje się najczęściej skrypt:

$username = 'xxxxxxx_1'; - "_1" - wyróżnik bazy dla tego skryptu
$password = 'xxxxxxxxxx';
$database = 'xxxxxxx_1';

$m = $_GET['m'];
$order = $_GET['order'];
$order1 = 'nazwisko';

switch ($order) {
case 'n':
$order1 = 'nazwisko';
break;
case 'l':
} - kilka case-ów do wyboru kolumny sortowanej


//pierwsze 'łączenie' z bazą do pobrania wiersza opisującego nagłówki strony
$link = mysql_connect('sql.xxx.xxx.pl:3306', $username, $password) or die('Nie można się połączyć: ' . mysql_error());
@mysql_select_db($database) or die("Nie udało się wybrać bazy danych");
$result=mysql_query("SELECT * FROM cmentarz WHERE id = ".$m);

$rek = mysql_fetch_array($result);
$id=$rek["id"];
$nazwa=$rek["nazwa"];
$lokal=$rek["lok"];
$kat=$rek["kat"];
$opr=$rek["opr"];

//tu kilka instrukcji php pobierających tekst z pliku zewnętrznego

mysql_close($link);
mysql_free_result ($result);
?>

Wszystko to wstawiło mi się w część <head>. Nie wiem, czy to ma znaczenie?
Dalej leci część <body>. Wyświetlane są pierdółki pobrane z porzedniej operacji SELECT. Potem następuje właściwe pobranie danych z innej tabeli tej samej bazy.

$link = mysql_connect('sql.xxx.xxx.pl:3306', $username, $password) or die('Nie można się połączyć: ' . mysql_error());
@mysql_select_db($database) or die("Nie udało się wybrać bazy danych");
$result=mysql_query("SELECT * FROM polegli p, cmentarz c WHERE miejsce_p='$m' AND c.id=p.miejsce_p ORDER BY ".$order1);

$num=mysql_numrows($result);
if ($num==0)
{
echo $l_nazwisk2;
echo "</td></tr>";
echo "</table><br>";
}
else
{
echo $num
?>
</td></tr>
</table><br>
<center>
<table border="1" cellspacing="2" cellpadding="2" bgcolor="#FFFFFF">

//Tu konstrukcja nagłówków tabeli <th>

<!-- początek pętli wypełniającej tabelę --->
<?
while ($rek = mysql_fetch_array($result))
{
$nazwisko=$rek["nazwisko"];
if ($nazwisko==null) {$nazwisko='-';}
$imie=$rek["imie"];
if ($imie==null) {$imie='-';}
$stopien=$rek["stopien"];
if ($stopien==null) {$stopien='-';}
?>
<tr>
<td><font face="Arial, Helvetica, sans-serif" size=1><? echo $nazwisko; ?></font></td>
<td><font face="Arial, Helvetica, sans-serif" size=1><? echo $imie; ?></font></td>
<td><font face="Arial, Helvetica, sans-serif" size=1><? echo $stopien; ?></font></td>
</tr>
<?
}
echo "</table></center>";
mysql_free_result($result);
mysql_close($link);
}
?>


I to wszystko... Nie wygląda mi na zapętlone zapytanie, ale może się nie znam.
Proszę pomóżcie.
Cała strona do obejrzenia pod http://www.tgcp.polegli.pl
W/w skrypt do obejrzenia pod http://www.polegli.tgcp.pl/miasto.php?lng=...788&order=n
nevt
else
{
echo $num
?>


jaka liczba wyświetla się w tej linijce... przy złej kostrukcji zapytania lub nieprawidłowych danych dla klauzuli WHERE moze wywalać nawet całą tabelę - nie widzę zabezpieczenia w postaci stronicowania wyników, jakiś LIMIT w zapytaniu na przykład...
wicy
$num=mysql_numrows($result);
if ($num==0)
{
echo $l_nazwisk2;
echo "</td></tr>";
echo "</table><br>";
}
else
{
echo $num

Liczba nazwisk w bazie. Jeśli $num==0 wyświetla "Brak" (zmienna tekstowa wprowadzona dla różnych wersji językowych). Jeśli $num<>0 wyświetla liczbę wierszy.
Czy ustalenie limitów, stronicowania ma wpływ na error #1226?? Czy to tylko raczej "ładny styl" pisania?
Jeśli nie ma to wpływu na ilość zapytań do bazy, to póki co odpuszczę kosmetykę.

Aha.. trochę mało przejrzyście podałem przykład. Oczywiście dalesze odczyty wierszy i konstrukcja tabeli są w części po ELSE
I oczywiście chyba zrobiłem błąd bo zamknięcie bazy jest tylko w części ELSE. Więc dla miast zerową liczbą osób $link się nie zamyka.
Czy to może być przyczynąquestionmark.gif?

No i nie pomogło sad.gif
O ile z błędu zniknęło "max_question" o tyle pojawił się komunikat:
#1226 - User 'xxx' has exceeded the 'busy_time' resource (current value: 600000000)

O co tu jeszcze może chodzić? Czy zapytanie wykonuje się za długo?
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.