mysql加入同一个表两次运行速度很慢,结果错误

时间:2016-08-28 20:03:44

标签: mysql database

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个。

我怎样才能更好更快地完成?

谢谢

2 个答案:

答案 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

通过这种方式,您只能链接到该表一次,并且只有在您的活动计数处于活动状态时才会有条件地计数。

祝你好运!