如何针对评级表优化JOIN和AVG语句

时间:2011-12-08 03:21:30

标签: mysql left-join average

我基本上有两个表,一个'服务器'表和一个'server_ratings'表。我需要优化我当前的查询(它可以工作,但需要大约4秒)。有什么方法可以做得更好吗?

SELECT ROUND(AVG(server_ratings.rating), 0), server.id, server.name
FROM server LEFT JOIN server_ratings ON server.id = server_ratings.server_id
GROUP BY server.id;

2 个答案:

答案 0 :(得分:1)

查询看起来没问题,但确保您有正确的索引

  • id表格中的server列上 - 可能是主键,
  • 位于server_id表中的server_ratings列,

如果没有帮助,那么rating列添加到server表中并定期计算(请参阅this answer about Cron jobs)。这样您就可以节省计算时间。它们可以单独制造,例如。每分钟,但可能一些不太频繁的计算就足够了(取决于你的数据的动态程度)。

还要确保查询正确的表 - 在您提到的servers表的问题中,但在代码中引用了server表。可能是一个错字:)

答案 1 :(得分:0)

这应该稍快一些,因为首先执行聚合函数,导致JOIN操作更少。

SELECT s.id, s.name, r.avg_rating
FROM   server s
LEFT   JOIN (
    SELECT server_id, ROUND(AVG(rating), 0) AS avg_rating
    FROM   server_ratings
    GROUP  BY server_id
    ) r ON r.server_id = s.id

主要观点匹配索引。主键自动编入索引。确保您在server_ratings.server_id上也有一个。