2010-01-29 9 views
5

Kann ich irgendwie Tabellen beitreten und die Verwendung von distinct in der folgenden MySQL-Abfrage vermeiden. laded_by_id zeigt die Benutzer-ID an, wer diesen Benutzer eingeladen hat.Wie optimiert man eine verschachtelte Abfrage?

SELECT 
    user1.id, count(distinct user2.id) AS theCount, count(distinct user3.id) AS theCount2 
FROM 
    users AS user1 
LEFT OUTER JOIN 
    users AS user2 ON user2.invited_by_id=user1.id 
LEFT OUTER JOIN (
    SELECT id, invited_by_id FROM users WHERE signup_date >= NOW() - INTERVAL 30 DAY 
) AS user3 ON user3.invited_by_id=user1.id 
GROUP BY user1.id; 
+0

Warum brauchen Sie deutlich? Es scheint mir, dass Benutzer X nur einmal von Benutzer Y * eingeladen werden darf. –

+0

@Lieven Da die Tabelle zweimal verknüpft wird, können Sie doppelte Zeilen erhalten. –

Antwort

1

etwas probieren so änderte ich die Namen der Unterabfragetabellen, um es ein wenig klarer zu machen:

Wenn das etwas ist Sie laufen oft, stellen Sie sicher, dass user.invited_by_id indiziert ist!

1

Wenn Sie eine Version von MySQL größer als 5.0.37 laufen haben Sie eine Profiler zur Verfügung, dass Sie eine ziemlich gute Vorstellung davon geben könnte, wo die Engpässe auf jede Abfrage sind. Das könnte ein guter Ausgangspunkt sein - Sie könnten die Ausgabe in die ursprüngliche Frage bearbeiten, wenn Sie nicht sicher sind, wie Sie sie am besten interpretieren.

+0

Er ist auf MySQL. –

+0

Guter Punkt, keine Ahnung, warum ich dort das Falsche eintippte. – glenatron

+0

Ah ... Das macht jetzt viel mehr Sinn! :) –

3

Ich gehe hier davon aus, dass Sie versuchen zu zählen, wie oft ein Benutzer eingeladen wurde und wie oft dieser Benutzer in den letzten 30 Tagen eingeladen wurde.

In diesem Fall können Sie die Abfrage mit einer einfachen bedingten Summe tun könnte als:

select user1.id, count(user2.id) as tehCount, sum(user2.signup_date >= NOW() - INTERVAL 30 DAY) as theCount2 
from users as user1 
left outer join users as user2 on user2.invited_by_id = user1.id 
group by user1.id 

Wenn die NULL-Werte in theCount2 ein Problem sein wird, eine coalesce verwenden wie:

coalesce(sum(user2.signup_date >= NOW() - INTERVAL 30 DAY), 0) 
Verwandte Themen