wydajnosc wielokrotnych join'ów
Adam - 16-11-2005 21:31
wydajnosc wielokrotnych join'ów
Mam problem wydajnosciowy i poszukuje mozliwych optymalizacji
Probuje wielokrotnym join'em połączyć wyniki z subselect'ów Oto pseudokod zbliżony do składni MySQL 4.1/5.0
SELECT id, v1.attr1, v2.attr2, v3.attr3, v4.attr4 FROM ( SELECT id, SUM(x) as attr1 FROM .... GROUP BY id ) AS v1 LEFT JOIN ( SELECT id, COUNT(y) as attr2 FROM .... GROUP BY id ) AS v2 ON v1.id = v2.id LEFT JOIN ( SELECT id, AVG(z) as attr3 FROM .... GROUP BY id ) AS v3 ON v1.id = v3.id LEFT JOIN ( SELECT id, SUM(q) as attr4 FROM .... GROUP BY id ) AS v4 ON v1.id = v4.id
Interesuje mnie pełna lista id więc nie mogę tu użyć zwykłego where'a a z drugiej strony każde z podzapytań to zupełnie inne wyliczenie nie dające się pogodzić ze sobą.
Problem w tym iż całość działa dużo wolniej niż jakbym wypełniał wszystkie pola atrybutów oddzielnymi UPDATE/SELECT'ami. Jak zoptymalizować/przereorganizować taką konstrukcję by działała optymalnie. Każde z podzapytań zwraca kilkadziesąt do kilkuset rekordów.
fasol - 17-11-2005 11:21
> Mam problem wydajnosciowy i poszukuje mozliwych optymalizacji > > Probuje wielokrotnym join'em połączyć wyniki z subselect'ów > Oto pseudokod zbliżony do składni MySQL 4.1/5.0 > > SELECT id, v1.attr1, v2.attr2, v3.attr3, v4.attr4 > FROM > ( SELECT id, SUM(x) as attr1 > FROM .... > GROUP BY id > ) AS v1 > LEFT JOIN > ( SELECT id, COUNT(y) as attr2 > FROM .... > GROUP BY id > ) AS v2 > ON v1.id = v2.id > LEFT JOIN > ( SELECT id, AVG(z) as attr3 > FROM .... > GROUP BY id > ) AS v3 > ON v1.id = v3.id > LEFT JOIN > ( SELECT id, SUM(q) as attr4 > FROM .... > GROUP BY id > ) AS v4 > ON v1.id = v4.id > > > Interesuje mnie pełna lista id więc nie mogę tu użyć zwykłego where'a > a z drugiej strony każde z podzapytań to zupełnie inne wyliczenie > nie dające się pogodzić ze sobą. > > Problem w tym iż całość działa dużo wolniej niż > jakbym wypełniał wszystkie pola atrybutów oddzielnymi > UPDATE/SELECT'ami. Jak zoptymalizować/przereorganizować > taką konstrukcję by działała optymalnie. > Każde z podzapytań zwraca kilkadziesąt do kilkuset rekordów.
A może wystarczy:
SELECT id, SUM(x) as attr1, COUNT(y) as attr2, AVG(z) as attr3, SUM(q) as attr4 FROM .... GROUP BY id
Adam - 17-11-2005 11:21
> A może wystarczy: > > SELECT id, SUM(x) as attr1, COUNT(y) as attr2, AVG(z) as attr3, SUM(q) as > attr4 > FROM .... > GROUP BY id
niestety nie ze względu na to iż dane funkcje grupujące dzialaja na różnych tabelach i warunkach ograniczających (WHERE)
Przypuszczam iż problem wydajnościowy wiąże się z tego iż w zapytaniu opinającym brak jest tabeli fizycznej na której dałoby się założyć odpowiednie indeksy :(
Paweł Matejski - 18-11-2005 12:01
Adam wrote: > Mam problem wydajnosciowy i poszukuje mozliwych optymalizacji > > Probuje wielokrotnym join'em połączyć wyniki z subselect'ów [...] > Interesuje mnie pełna lista id
To LEFT JOIN Ci sprawy nie rozwiąże, jeśli w pierwszym subselekcie nie masz pełnej listy id. Jeśli już joina chcesz użyć, to raczej FULL OUTER JOIN.
> więc nie mogę tu użyć zwykłego where'a > a z drugiej strony każde z podzapytań to zupełnie inne wyliczenie > nie dające się pogodzić ze sobą.
Co czarujesz - warunki z whera przenosi cię do funkcji agregujących przy pomocy CASE.
> Problem w tym iż całość działa dużo wolniej niż > jakbym wypełniał wszystkie pola atrybutów oddzielnymi > UPDATE/SELECT'ami. Jak zoptymalizować/przereorganizować > taką konstrukcję by działała optymalnie. > Każde z podzapytań zwraca kilkadziesąt do kilkuset rekordów.
spróbuj :
select id, sum(attr1), sum(attr2) from ( select id, sum(x) as attr1, 0 from ... where ... group by id union all select id, 0,sum(y) as attr2 from ... where ... group by id ) group by id;
-- P.M.
Adam - 18-11-2005 12:01
> To LEFT JOIN Ci sprawy nie rozwiąże, jeśli w pierwszym subselekcie nie > masz pełnej listy id. Jeśli już joina chcesz użyć, to raczej FULL OUTER > JOIN.
Zeby jeszcze taki w Mysql był :/
> select id, sum(attr1), sum(attr2) > from > ( > select id, sum(x) as attr1, 0 from ... where ... > group by id > union all > select id, 0,sum(y) as attr2 from ... where ... > group by id > ) > group by id; >
o tym nie pomyślałem a dość fajne rozwiązanie o tyle fajne iż mozna tu użyć tabeli tymczasowej z pozakładanymi indeksami
thx
zanotowane.pldoc.pisz.plpdf.pisz.pleffulla.pev.pl
|
=?ISO-8859-2?Q?Poszukjue_ksi=B1=BFki_"Oracle_?= =?ISO-8859-2?Q?optymalizacja_wydajno=B6ci"..?=
mysql+php - =?ISO-8859-2?Q?wydajno=B6=E6_przy_olbrzymiej_i?==?ISO-8859-2?Q?lo=B6ci_rekord=F3w?=
[ORACLE] Dodanie kolumny typu BLOB - =?ISO-8859-2?Q?wp=B3yw_na?==?ISO-8859-2?Q?_wydajno=B6c?=
[MySQL] Wybierz tylko te rekordy z t1 =?ISO-8859-2?Q?kt=F3rych_?==?ISO-8859-2?Q?nie_ma_w_t2=2E_JOIN_=3F?=
btrieve 6.15; geo-info2000; mala wydajnosc sieci - prosba o pomoc
Wydajność baz danych w zależności od poziomu izolacji ANSI/ISO
[PostgreSQL] =?ISO-8859-2?Q?Sprz=EAt_a_wydajno=B6=E6?=
=?iso-8859-2?q?Problemy_z_wydajno=B6ci=B1_Firebird'a_po_upgra de.?=
Ciekawosta =?iso-8859-2?q?wydajno=B6ci?= DISTINCT i GROUP BY na PostgreSQLu
[pgsql] 8.2 vs 8.1 - =?ISO-8859-2?Q?wydajno=B6=E6?=
zanotowane.pldoc.pisz.plpdf.pisz.plets2.xlx.pl
Cytat
Decede mihi sole - nie zasłaniaj mi słonca. Gdy kogoś kochasz, jesteś jak stworzyciel świata - na cokolwiek spojrzysz, nabiera to kształtu, wypełnia się barwą, światłem. Powietrze przytula się do ciebie, choćby był mróz, a ty masz w sobie tyle radości, że musisz ją rozdawać wokoło, bo się w tobie nie mieści Hoc fac - tak czyń. A tergo - od tyłu; z tyłu. I czarne włosy posiwieją. Safona |
|