Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [Mysql]Group by optymalizacja
Crisu
post
Post #1





Grupa: Zarejestrowani
Postów: 59
Pomógł: 0
Dołączył: 11.08.2006

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


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.
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 4)
vokiel
post
Post #2





Grupa: Zarejestrowani
Postów: 2 592
Pomógł: 445
Dołączył: 12.03.2007

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


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
Go to the top of the page
+Quote Post
Crisu
post
Post #3





Grupa: Zarejestrowani
Postów: 59
Pomógł: 0
Dołączył: 11.08.2006

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


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 ?
Go to the top of the page
+Quote Post
Ges
post
Post #4





Grupa: Zarejestrowani
Postów: 61
Pomógł: 9
Dołączył: 22.02.2008

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


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.
Go to the top of the page
+Quote Post
Crisu
post
Post #5





Grupa: Zarejestrowani
Postów: 59
Pomógł: 0
Dołączył: 11.08.2006

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


Wiem, że zabrzmi pesymistycznie ale partycjnowania także nie mogę użyć (IMG:style_emoticons/default/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) ?
Go to the top of the page
+Quote Post

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

 



RSS Aktualny czas: 13.10.2025 - 05:22