Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [Mysql]Group by optymalizacja
Forum PHP.pl > Forum > Bazy danych > MySQL
Crisu
Witam!
Mamy taki przypadek. Jest jedna wieksza tabela , założmy 2 mln rekordów do której dołączamy kilka mniejszych po 200-400 każda.
Czyli coś w stylu :

  1. SELECT st.pole2,bt.pole1,bt.pole2, st.pole1,MAX(bt.pole3)
  2. FROM big_table bt
  3. LEFT JOIN small_table st ON (st.id_small=bt.id_small)
  4. WHERE bt.pole2='T' AND bt.pole1=21
  5. GROUP BY st.pole2


Wszystko fajnei działą gdy duża tabela ma ok 100k rekordów. Gdy wchodzimy na większa ilość krotek , wszystko diametralnie zwalnia.
Czy ktoś ma może pomysł jak takie zapytanko zooptymalizować ? Indeksy są założone na PK i FK , i testowałem już kilka wariantów z indeksami na innych polach (m.in na tym po którym grupuje). Efekt zerowy.
Silnik InnoDB.
vokiel
Jeśli nie używasz transakcji na poziomie bazy to zmień na MyISAM - jesz szybsze.

Załóż klucze na pola w warunku WHERE, dodatkowo możesz zobaczyć jak wygląda zapytanie wg bazy dodając DESCRIBE przed zapytaniem.
Poza tym bt.pole2='T', może da się warunek sprowadzić do liczby, czyli zamiast I,T,P zrobić 1,2,3, klucze na wartościach liczbowych są szybsze
Crisu
Transakcji uzywam, wiec musi być InnoDB.
Właśnie sprawa jest dziwna, bo desc pokazuje wszędzie użycie indeksów, maksymalnie analizowane jest 520 rekordów.
Tego warunku pole2='T' tez nie moge sprowadzić do liczby, bo po prostu takie dane dostaje : )
Może ma to jakiś związek z tym, że grupuje tylko po jednym polu a wyświetlam poza max , także inne ?
Ges
Przy takiej ilości wydaje mi się, że ciężko bedzie Ci już coś zoptymalizować samym kodowaniem.

Jak dla mnie rozwiązaniem dla Ciebie przyszłościowym byłoby skorzystanie z partycjonowania bazy danych.
Dzielisz tą wielką tabele na partycję (każda zawiera "kawałek" Twojej bazy).
Wykonując takie zapytanie przy konfiguracji z partycjami wyśle zapytanie do każdej partycji osobno, każda partycja zwróci swój "kawałek odpowiedzi" potem zostaną złożone do "kupy".

Polecam lekturę:
http://dev.mysql.com/doc/refman/5.4/en/par...g-overview.html

Są jeszcze klastry, ale to może być na wyrost mocno.

Btw. vokiel: od kiedy MyIsam jest szybsze od InnoDb ? InnoDb jest ~30% wydajniejsze w większości przypadków.
MyIsam będzie lepszym wyborem gdy zaczniemy używać Full Tree Search oraz dużej ilości BLOBów.
Crisu
Wiem, że zabrzmi pesymistycznie ale partycjnowania także nie mogę użyć smile.gif (serwer stoi na debianie a tam jest mysql w starszej wersji jeszcze ) Co prawda zawsze można zrobić partycje ręcznie (czytaj osobne tabele) ale w tym wypadku to się troche mija z celem.

Może macie pomysł jak to inaczej zapisać (np w podzapytaniach) ?
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.