Как оптимизировать вложенный запрос?
-
23-09-2019 - |
Вопрос
Могу ли я каким-то образом объединить таблицы и избежать использования distinct в следующем запросе MySQL.invited_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;
Решение
Попробуйте что-то вроде этого, я изменил имена таблиц вложенных запросов, чтобы сделать их немного понятнее:
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
индексируется!
Другие советы
Я предполагаю здесь, что вы пытаетесь подсчитать, сколько раз пользователь был приглашен, и подсчитать, сколько раз этот пользователь был приглашен за последние 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 как :
coalesce(sum(user2.signup_date >= NOW() - INTERVAL 30 DAY), 0)
Если вы используете версию MySQL выше 5.0.37, у вас есть Профилировщик доступно для вас, что могло бы дать вам довольно хорошее представление о том, где находятся узкие места в любом запросе.Это может быть хорошей отправной точкой - возможно, вы могли бы отредактировать выходные данные в исходном вопросе, если вы не уверены в том, как лучше их интерпретировать.