Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Poprawienie wydajności bazy
Forum PHP.pl > Forum > Bazy danych > MySQL
Gruchol
Witam,
Na wstępie chciałbym powiedzieć że jestem zielony jeżeli chodzi o linuxa i prosiłbym o pisanie jak najbardziej zrozumiale.
Posiadam sporą bazę MySQL która strasznie przymula.
Uruchomiłem MySQLTuner który pokazał mi coś takiego :
http://wklej.org/id/1633653/
Szukałem tych linijek w my.cnf
tmp_table_size (> 16M)
max_heap_table_size (> 16M)
Jednak ich nie znalazłem.
Proszę o wyjaśnienie jak najprościej się da co mogę zrobić aby poprawić wydajność.
Pozdrawiam.

@edit
Dopisałem to do my.cnf
tmp_table_size = 16M
max_heap_table_size = 16M
I teraz ten komunikat na samym dole zniknął.
Co jeszcze mogę zrobić ?
aniolekx
tak naprawdę to nie wiadomo co oznacza przymula, wiesz jak masz bazę na kiepskiej maszynie to może tu jest problem smile.gif
pyzatym zawsze możesz sprawdzić jakie zapytania trwają najdłużej, może brakuje indeksów
ograniczyć liczbę zapytań do bazy stosując rożne formy cachowania
Gruchol
A czy istnieje jakaś aplikacja która pozwoli mi sprawdzić które zapytanie wykonuje się najdłużej ?
Co do słabej maszyny, baza stała na maszynie 6gb ramu 4x3.0 ghz i tam było praktycznie to samo.
Teraz zrobiłem tak że mysql stoi na osobnej maszynie a na osobnej stoi php5, nginx itp.
Jest trochę lepiej jednak nadal strona strasznie wolno chodzi.
mmmmmmm
Przejrzyj slow.log.
W pliku my.cnf masz zdefiniowane, gdzie leży:
log_slow_queries = /var/log/mysql/mysql-slow.log
long_query_time = 2
log-queries-not-using-indexes
Gruchol
A co muszę zrobić aby te błędy naprawić ?
[exclamation.gif] InnoDB is enabled but isn't being used
[exclamation.gif] Total fragmented tables: 2
Pyton_000
Olać, to mówi że masz odpalone InnoDB ale nie używasz tego nigdzie i że 2 tabele mozna zoptymalizować (zdrefragmentować)
Gruchol
Kupiłem lepszego VPSa pod bazę (3gb ramu, 2x2,5 GHZ) i cały czas muli tak samo.
A mysqltuner pokazuje : http://wklej.org/id/1634295/
Już nie wiem co mam zrobić :/
Pyton_000
a co zwraca slow.log o które prosił @mmmmmmm questionmark.gif
b4rt3kk
Cytat(Gruchol @ 13.02.2015, 15:44:26 ) *
Kupiłem lepszego VPSa pod bazę (3gb ramu, 2x2,5 GHZ) i cały czas muli tak samo.
A mysqltuner pokazuje : http://wklej.org/id/1634295/
Już nie wiem co mam zrobić :/


Muli, bo musi mulić - widocznie aplikacja, która korzysta z bazy jest mało optymalnie napisana. Przedstaw jakieś przykładowe zapytania z podstrony, która najbardziej muli.

Zabrałeś się do tego, za przeproszeniem, od d... strony, kupując od razu nowy vps. Najpierw optymalizujesz zapytania, triggery, indexy, funkcje jak to nie pomaga to lepszy sprzęt.
Gruchol
slowlog pokazuje :
http://wklej.org/id/1634306/
Pyton_000
To teraz zopytmalizuj te zapytanie a serwis zacznie latać.
Gruchol
Niestety nie znam się aż tak bardzo aby optymalizować skrypty :/
W moim pliku to zapytanie wygląda tak :

  1. $qry = $db->prepare ( "SELECT name, honor, guild_id,
  2. (SELECT user_data.user_name FROM user_data WHERE user_data.user_id = leader_id) AS leader,
  3. (SELECT Count(user_data.guild_id) FROM user_data WHERE user_data.guild_id = guilds.guild_id) AS members
  4. FROM guilds
  5. ORDER BY honor DESC, members DESC LIMIT :pos, 15" );
  6. $qry->bindParam ( ':pos', $posFrom, PDO::PARAM_INT );
  7. $qry->execute ();


Był bym bardzo wdzięczny gdybyś pomógł mi to zoptymalizować.
Pyton_000
Zerknij to:
  1. SELECT
  2. g.name, g.honor, g.guild_id, u.user_name AS leader, COUNT(ug.guild_id) AS members
  3. FROM
  4. guilds g
  5. JOIN user_data u ON(u.user_id = g.leader_id)
  6. JOIN uesr_data ug USING(guild_id)
  7. ORDER BY
  8. honor DESC, members DESC
  9. GROUP BY ug.guild_id
  10. LIMIT :pos,15


A jak to nie zadziała to sprawdź czy masz indeksy na polach:
user_data.guild_id
guilds.guild_id
user_data.user_id
Gruchol
Nadal jest tak samo :/
(Tzn. aktualnie nie mam możliwość sprawdzenia czy kod działa jednak po wgraniu go muli cały czas tak samo :/ )
sazian
  1. EXPLAIN
  2. SELECT name, honor, guild_id,
  3. (SELECT user_data.user_name FROM user_data WHERE user_data.user_id = leader_id) AS leader,
  4. (SELECT Count(user_data.guild_id) FROM user_data WHERE user_data.guild_id = guilds.guild_id) AS members
  5. FROM guilds
  6. ORDER BY honor DESC, members DESC LIMIT 0, 15;

pokaż wynik
b4rt3kk
Cytat(Pyton_000 @ 13.02.2015, 16:28:37 ) *
Zerknij to:
  1. SELECT
  2. g.name, g.honor, g.guild_id, u.user_name AS leader, COUNT(ug.guild_id) AS members
  3. FROM
  4. guilds g
  5. JOIN user_data u ON(u.user_id = g.leader_id)
  6. JOIN uesr_data ug USING(guild_id)
  7. ORDER BY
  8. honor DESC, members DESC
  9. GROUP BY ug.guild_id
  10. LIMIT :pos,15


A jak to nie zadziała to sprawdź czy masz indeksy na polach:
user_data.guild_id
guilds.guild_id
user_data.user_id


Wg mnie ten join, tylko po to, żeby zrobić counta jest tu niepotrzebny. Podzapytanie sobie lepiej poradzi.

  1. SELECT
  2. g.name, g.honor, g.guild_id, u.user_name AS leader, (SELECT COUNT(ug.guild_id) FROM user_data WHERE guild_id = guilds.guild_id) AS members
  3. FROM
  4. guilds g
  5. JOIN user_data u ON(u.user_id = g.leader_id)
  6. ORDER BY
  7. honor DESC, members DESC
  8. GROUP BY ug.guild_id
  9. LIMIT :pos,15


W ogóle to trochę bez sensu, żeby robić joina tylko po to, żeby zrobić counta. Już lepszym rozwiązaniem by było:

  1. SELECT
  2. g.name, g.honor, g.guild_id, u.user_name AS leader, ct AS members
  3. FROM
  4. guilds g
  5. JOIN user_data u ON(u.user_id = g.leader_id)
  6. JOIN (SELECT guild_id, COUNT(*) ct FROM user_data GROUP BY guild_id) gc ON gc.guild_id = g.guild_id
  7. ORDER BY
  8. honor DESC, members DESC
  9. GROUP BY ug.guild_id
  10. LIMIT :pos,15
Pyton_000
Może i tak, nie robiłem testów wink.gif Nie chciało mi się, na szybko pisałem. Czasami wyniki mogą być różne więc każde rozwiązanie można przetestować.
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.