Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [MySQL] Optymalizacja zapytań
pitu
post 13.12.2010, 10:59:41
Post #1





Grupa: Zarejestrowani
Postów: 476
Pomógł: 96
Dołączył: 10.04.2008
Skąd: Koszalin

Ostrzeżenie: (0%)
-----


Witam

Posiadam stronę WWW, na której użytkownicy wyszukują muzykę. Każda nowa fraza, która jest wyszukiwana jest zapisywana do bazy. W frazach istniejących aktualizowany jest licznik wyszukań. Aktualnie w dość szybkim czasie tabela zapełnia się rekordami, w miesiąc dochodzi nawet do 30-50k nowych rekordów. Przy każdym wyszukaniu cała tabela jest przeszukiwana, przez co MySQL dość mocno obciąża CPU serwera.

Na razie staram się systematycznie czyścić tabele, lecz wolałbym jakieś inne rozwiązanie usprawniające/przyspieszające. Frazy jak i ilości wyszukań wykorzystywane są do chmury tagów, ostatnio wyszukiwanych oraz najlepszych dlatego wolałbym nie czyścić tabel.

Zrzut tabeli
  1. CREATE TABLE `mp3_search` (
  2. `search_id` int(11) NOT NULL AUTO_INCREMENT,
  3. `search_txt` text NOT NULL,
  4. `search_ile` int(11) NOT NULL DEFAULT '0',
  5. `search_data` text character SET latin1 collate latin1_general_ci NOT NULL,
  6. `search_datal` text character SET latin1 collate latin1_general_ci NOT NULL,
  7. `search_datarss` text character SET latin1 collate latin1_general_ci NOT NULL,
  8. PRIMARY KEY (`search_id`)
  9. )


Wykonywane zapytania podczas wyszukiwania muzyki przez użytkownika
  1. SELECT search_txt mp3_search WHERE search_txt='szukany tytul'
  2.  
  3. jeżeli fraza jest w bazie:
  4. UPDATE mp3_search SET search_ile=search_ile+1, search_datal='".date("Y.m.d H:i")."', search_datarss='".date("D, d M Y G:i:s")." +0000' WHERE search_txt='szukany tytul'
  5.  
  6. jeżeli frazy nie ma w bazie:
  7. INSERT INTO mp3_search(`search_txt`, `search_data`, `search_datal`, `search_ile`, `search_datarss`) VALUES ('szukany tytul', '".date("Y.m.d H:i")."', '".date("Y.m.d H:i")."', '1', '".date("D, d M Y G:i:s")." +0000')


--------------------
HTML/CSS/JS: jsfiddle
SQL: sqlfiddle
Go to the top of the page
+Quote Post
phpion
post 13.12.2010, 11:08:37
Post #2





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Po pierwsze - dodaj indeks na pole search_txt. Po drugie - zastanów się nad poprawnością typów pól, jakie zastosowałeś. Wspomniany search_txt powinien być VARCHAR, a pola z datami powinny być typu DATETIME, a nie tekstowego.
Go to the top of the page
+Quote Post
pitu
post 13.12.2010, 11:41:38
Post #3





Grupa: Zarejestrowani
Postów: 476
Pomógł: 96
Dołączył: 10.04.2008
Skąd: Koszalin

Ostrzeżenie: (0%)
-----


Dziękuję za odpowiedź.

Wykonałem następujące rzeczy:
  1. ALTER TABLE mp3_search MODIFY search_txt VARCHAR(255);
  2. ALTER TABLE mp3_search MODIFY search_data DATETIME;
  3. ALTER TABLE mp3_search MODIFY search_datal DATETIME;
  4. ALTER TABLE mp3_search MODIFY search_datarss DATETIME;
  5. CREATE INDEX index_mp3 ON mp3_search(search_txt(255));


Czy ma dużą różnicę nadanie indeksu na całe 255 znaków tak jak to wykonałem? Czy zapytania Select należy modyfikować pod nowy indeks?

Z góry dziękuję i pozdrawiam


--------------------
HTML/CSS/JS: jsfiddle
SQL: sqlfiddle
Go to the top of the page
+Quote Post
franki01
post 20.12.2010, 12:32:21
Post #4





Grupa: Zarejestrowani
Postów: 508
Pomógł: 75
Dołączył: 2.11.2005
Skąd: Bydgoszcz

Ostrzeżenie: (0%)
-----


Ja mam dwie uwagi:

1) Z tego, co przedstawiłeś wynika, że nie masz łączenia tabel. Upewnij się, że rodzaj składowania danych tabeli to MyISAM. Sprawuje się szybciej niż InnoDB w Twoim przypadku, gdzie wyszukujesz w tekście w jednej tabeli.

2) VARCHAR zmień na CHAR. Różnica jest taka, że pola typu CHAR są stałej długości i nie potrzeba kolejnych obliczeń, aby znaleźć dalsze pola. Minus taki, że CHAR za każdym razem rezerwuje 255 bajtów danych, podczas gdy VARCHAR tyle, ile zajmuje tekst. Tańsze jest dokupienie 100 GB HHD/SSD niż dokupienie 1 GHz procesora. Ta zamiana ma sens tylko wtedy, gdy rodzaj składowania danych to MyISAM, bo przy InnoDB nie ma to tak wielkiego znaczenia.

Do tego możesz znaleźć optymalną długość pola search_txt:
Kod
SELECT * FROM `mp3_search` PROCEDURE ANALYSE()

Patrzysz na maksymalną długość tekstu w kolumnie i na jej podstawie (+ mały zapas) określasz najbardziej odpowiednią wielkość pola.

Długość indeksu najwygodniej, gdy zapełnia całą przestrzeń pola. Nigdy nie oszczędzaj dysku kosztem zużycia procesora. Wychodzi dużo taniej.

Ten post edytował franki01 20.12.2010, 12:34:07
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 19.07.2025 - 02:06