On Thu, Apr 14, 2005 at 07:13:32PM +0200, Wiktor R. Braun wrote:
> Witam,
> proszę o pomoc w optymalizacji zapytania MySQL'owego. Aktualnie trwa
> zbyt długo... ~20 sek.
Taka sztuczka z mysqlem jest...
> 1) zostali podłączeni przed 2005 rokiem,
Ze w users jest "creationdate" co już prawie dobrze użyłeś...
> 2) mają włączone komputery,
> 3) bez zawieszonych płatności :)
>
> LMS v1.4.x
>
> SELECT users.id AS id, CONCAT(UPPER(lastname), ' ', users.name) AS
> username, status, email, phone1, phone2, phone3, users.address, gguin,
> nip, pesel, zip, city, info, message, serviceaddr,
Sztuczka polega na tym aby tutaj pobierać tylko i wyłącznie user id
> COALESCE(SUM((type * -2 + 7) * value), 0.00)/(CASE COUNT(DISTINCT
> nodes.id) WHEN 0 THEN 1 ELSE COUNT(DISTINCT nodes.id) END) AS balance
> FROM users
> LEFT JOIN cash ON (users.id=cash.userid AND (type = 3 OR type = 4))
I złączyć cash, można pokusić się wcześniej o time >= 1104534000 (timestamp z
Sylwestra 2004).
Tylko że zrobić to do tabelki tymczasowej ( "DROP TABLE tmp_users;
CREATE TEMPORARY TABLE tmp_users SELECT ...")
> LEFT JOIN nodes ON (users.id=ownerid)
Zrób to jeszcze *przed* złączaniem cash. Tzn tmp_users jako tabelkę
userid takich że mają włączone komputery.
> LEFT JOIN assignments ON (users.id=assignments.userid)
> WHERE deleted = 0
Potem zrób delete from tmp_users gdy nie mają oni obciążeń (cały czas na
tabelce tymczasowej).
> ORDER BY balance asc
Dopiero teraz zrób policzenie salda i potem złącz to z *potrzebnymni*
danymi z users. Na czas tych operacji dobrze jest albo zalockować
tabelki tylko-do-odczytu albo po prostu uznać że nikt Ci nie dopisze co
cash nic.
Aha: mysql już tak ma.
kd.
--
Krzysztof Drewicz
Podsłuchane na pogrzebie: "Wiem, że to niezręcznie pytać o takie rzeczy w tej
chwili, ale przypominasz sobie, żeby on kiedykolwiek wspomniał coś o kodzie
źródłowym?" --- Charles Addams