Как оптимизировать вложенный запрос? - PullRequest
5 голосов
/ 29 января 2010

Могу ли я как-то объединить таблицы и избежать использования различных в следующем запросе MySQL. Invite_by_id показывает идентификатор пользователя, который пригласил этого пользователя.

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;

Ответы [ 3 ]

3 голосов
/ 29 января 2010

Я предполагаю, что здесь вы пытаетесь подсчитать, сколько раз пользователь был приглашен, и подсчет того, сколько раз этот пользователь был приглашен за последние 30 дней.

В этом случае вы можете выполнить запрос с простой условной суммой как:

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

Если пустые значения в theCount2 будут проблемой, используйте объединение как:

coalesce(sum(user2.signup_date >= NOW() - INTERVAL 30 DAY), 0)
1 голос
/ 30 января 2010

Попробуйте что-то вроде этого, я изменил имена таблиц подзапроса, чтобы сделать его немного более понятным:

Select
    user.id,
    all_time.total AS theCount, 
    last_month.total AS theCount2
From users AS user
Left Outer Join 
    (Select Count(id) as total, invited_by_id
     From users
     Group By invited_by_id) as all_time
       On all_time.invited_by_id = user.id
Left Outer Join
    (Select Count(id) as total, invited_by_id
     From users 
     Where signup_date >= NOW() - INTERVAL 30 DAY
     Group By invited_by_id) AS last_month 
       On last_month.invited_by_id = user.id

Если вы часто этим пользуетесь, убедитесь, что user.invited_by_id проиндексирован!

1 голос
/ 29 января 2010

Если вы используете версию MySQL больше 5.0.37, у вас есть Profiler , который может дать вам довольно хорошее представление о узких местах в любом запросе. Это может быть хорошей отправной точкой - вы можете отредактировать вывод в исходный вопрос, если вы не уверены, как лучше его интерпретировать.

...