使用连接的慢速mysql查询

使用连接的慢速mysql查询,mysql,performance,Mysql,Performance,我必须运行这个查询,它非常慢(4.86秒): 当我进行分析时,看起来复制到tmp表需要91%的时间(3.710409秒) 表的大小:用户——近100000条记录,日志——1443000条记录,用户阶段——66000条记录,用户标签——260000条记录 有适当添加的索引,如果你想我可以写所有的索引。如何重写查询或修改mysql设置以加快查询速度?假设最后一个活动位于用户表中,您可以将查询更改为以下内容: SELECT `users`.* FROM `users` LEFT JOI

我必须运行这个查询,它非常慢(4.86秒):

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

表的大小:用户——近100000条记录,日志——1443000条记录,用户阶段——66000条记录,用户标签——260000条记录


有适当添加的索引,如果你想我可以写所有的索引。如何重写查询或修改mysql设置以加快查询速度?

假设
最后一个活动
位于
用户
表中,您可以将查询更改为以下内容:

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;
SELECT users.* 
FROM users 
ORDER BY last_activity DESC 
您的查询仅从
users
表中选择列。
左联接确保表中的所有行至少出现一次。
distinct
正在删除其他表添加的重复项。因此,连接是不必要的

如果
last\u activity
位于另一个表中,则可能需要将该信息加入


您的联接可能花费了很多时间,因为您从各个表中获得了每个用户的行的叉积。

查询是根据用户的输入动态生成的。有时看起来是这样的:

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 

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

是否
用户.id
唯一?您应该只选择您需要的字段,而不是所有(
用户。*
)请发布表架构。查询应该显示什么?您实际上为什么要加入?您只选择了用户字段。很好,他可以删除他不需要的连接。但如果他不能将它们全部删除,他应该分组,而不是使用DISTINCT,因为它更快。@tntu。为什么您认为
分组方式
独立方式
快?您是否有关于何时/为什么更快的参考资料?个人经验。如果我错了,请提供一些论据。我总是渴望学习。@tntu。在大多数数据库中,
distinct
的算法使用与
groupby
相同的算法。
distinct
可能会有一些较小的效率,因为没有额外的聚合列,但性能通常非常相似。我只发现在一种情况下,GROUP BY比distinct快得多。查询非常长,11个表中的3个表中的数据约为数百万。组的表现是显著的。
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