SELECT `apps`.*,
COUNT(all_users.id) AS total_users,
COUNT(active_users.id) AS active_users
FROM `apps`
INNER JOIN `social_users` AS `all_users` ON `all_users`.`app_id` = `apps`.`id`
INNER JOIN `social_users` AS `active_users` ON `active_users`.`app_id` = `apps`.`id`
WHERE `active_users`.`is_active` = 'true'
GROUP BY `id`
ORDER BY `total_users` ASC LIMIT 30
OFFSET 0
我有2张桌子
apps -> id, name
social_user -> id, app_id, is_active
我想在apps表上运行查询,并显示所有用户和所有活跃用户 我两次加入社交用户 问题是,如果我加入它一次(无论哪个)它运行得非常快。第二次连接会导致性能下降,而且数字根本不准确,我得到180000个用户而不是750个。
我怎样才能更好更快地完成?
谢谢
答案 0 :(得分:5)
SELECT `apps`.*,
COUNT(all_users.id) AS total_users,
SUM(IF(all_users.is_active='true',1,0)) AS active_users
FROM `apps`
INNER JOIN `social_users` AS `all_users` ON `all_users`.`app_id` = `apps`.`id`
GROUP BY `id`
ORDER BY `total_users` ASC LIMIT 30
OFFSET 0
答案 1 :(得分:1)
速度将在很大程度上取决于您的索引,但是我看到的第一个问题是您需要将WHERE
子句移动到ON
表的active_users
子句中:
SELECT `apps`.*,
COUNT(all_users.id) AS total_users,
COUNT(active_users.id) AS active_users
FROM `apps`
INNER JOIN `social_users` AS `all_users` ON `all_users`.`app_id` = `apps`.`id`
INNER JOIN `social_users` AS `active_users` ON `active_users`.`app_id` = `apps`.`id`
AND `active_users`.`is_active` = 'true'
GROUP BY `id`
ORDER BY `total_users` ASC LIMIT 30
OFFSET 0
这至少可以为您提供正确数量的结果。为了避免链接两次,你可以使你的第二个COUNT()条件,考虑:
SELECT `apps`.*,
COUNT(all_users.id) AS total_users,
COUNT(IF(all_users.is_active = 'true',all_users.id,NULL)) AS active_users
FROM `apps`
INNER JOIN `social_users` AS `all_users` ON `all_users`.`app_id` = `apps`.`id`
GROUP BY `id`
ORDER BY `total_users` ASC LIMIT 30
OFFSET 0
通过这种方式,您只能链接到该表一次,并且只有在您的活动计数处于活动状态时才会有条件地计数。
祝你好运!