加入缓慢的mysql查询

时间:2013-12-02 15:31:35

标签: mysql performance

我必须运行此查询并且它非常慢(4.86秒):

SELECT DISTINCT (users.id), users . * 
FROM users
LEFT JOIN user_stages ON users.id = user_stages.user_id
LEFT JOIN user_tags ON users.id = user_tags.user_id
LEFT JOIN log ON log.user_id = users.id
ORDER BY last_activity DESC 

当我进行性能分析时,看起来像复制到tmp表需要91%的时间(3.710409秒)。

表的大小:用户 - 近100,000条记录,日志 - 1,443,000条记录,user_stages - 66,000条记录,user_tags - 260,000条记录。

正确添加索引,如果您愿意,我可以编写所有索引。如何重写查询或修改mysql设置以使此查询更快?

3 个答案:

答案 0 :(得分:2)

假设last_activity位于users表中,您可以将查询更改为以下内容:

SELECT users.* 
FROM users 
ORDER BY last_activity DESC 

您的查询仅选择users表中的列。 left join确保表中的所有行至少出现一次。 distinct正在删除其他表添加的重复项。因此,连接是不必要的。

如果last_activity在另一个表中,那么您可能需要将该信息加入。

您的联接可能需要花费很多时间,因为您从各个表中获取每个用户的行的交叉产品。

答案 1 :(得分:0)

SELECT `users`.* 
  FROM `users` 
    LEFT JOIN `user_stages` ON `users`.`id` = `user_stages`.`user_id` 
    LEFT JOIN `user_tags` ON `users`.`id` = `user_tags`.`user_id` 
    LEFT JOIN `log` ON `log`.`user_id` = `users`.`id` 
  GROUP BY `users`.`id`
  ORDER BY `last_activity` DESC;

答案 2 :(得分:0)

查询是根据用户的输入动态构建的。有时它看起来像这样:

SELECT DISTINCT (users.id), users . * 
FROM users
LEFT JOIN user_stages ON users.id = user_stages.user_id
LEFT JOIN user_tags ON users.id = user_tags.user_id
LEFT JOIN log ON log.user_id = users.id
WHERE user_stages.stage_id = 5
AND user_tags.tag_id = 10
ORDER BY last_activity DESC 

查询最初是使用GROUP BY编写的,但速度较慢(大约8秒)。我用DISTINCT替换了GROUP BY,它更快但速度不够快。如果您有任何建议,我将不胜感激。