如何在mysql

时间:2015-06-06 12:16:13

标签: php mysql

我有足球比赛列表。它有像match_id,团队得分,团队2得分,回合,match_date等列。

我需要来自数据库的所有行,并且该轮次的边距最高 保证金是球队得分和球队B得分的差异。

我的查询是

SELECT *,( SELECT MAX(ABS((z.home_score - z.away_score))) 
FROM tblform_matches z 
WHERE YEAR(z.match_date) = YEAR(tblform_matches.match_date) 
    AND z.round = tblform_matches.round ) as highest_margin 
from tblform_matches where some condtion

它是一个简化的查询,其中某些条件是一个大的查询字符串,用于根据过滤器选择某些指定的匹配项。

目前在数据库中有大约5000场比赛。

由于子查询,我的页面需要再加载4秒钟。

每轮有9场比赛,每年有超过20场比赛

我正在为php循环中的每个团队执行上述查询。我不能改变这件事。因为有很多计算显示统计数据。

对不起,如果我的问题没有清除,我在这里,如果我错过了一些东西,因为我是stakoverflow的新蜜蜂

提前致谢。

1 个答案:

答案 0 :(得分:1)

这是您的查询:

SELECT m.*,
       (SELECT MAX(ABS((m2.home_score - m2.away_score))) 
        FROM tblform_matches m2
        WHERE YEAR(m2.match_date) = YEAR(m.match_date) AND
              m2.round = m.round
       ) as highest_margin 
from tblform_matches m
where some condition;

据推测,优化这一点的最佳方法是关注。那好吧。你会想要那里正确的索引。

索引显然是解决方案,但由于year函数的问题,您遇到了问题。简单的解决方案是使用不等式:

SELECT m.*,
       (SELECT MAX(ABS((m2.home_score - m2.away_score))) 
        FROM tblform_matches m2
        WHERE m2.round = m.round
              (m2.match_date >= makedate(year(m.match_date), 1) and
               m2.match_date < makedate(year(m.match_date) + 1, 1)
              )                  
       ) as highest_margin 
from tblform_matches m
where some condtion;

子查询的最佳索引是tblform_matches(round, match_date, home_score, away_score)。前两列用于where子句。 select的第二个。

注意:如果您对数据结构进行了两次相对较小的更改,那么这可能会更好。添加匹配日期年份的列(冗余,但对索引很重要)。并且,为分数之间的差异的绝对值添加一列。然后查询将是:

SELECT m.*,
       (SELECT MAX(score_diff)
        FROM tblform_matches m2
        WHERE m2.round = m.round and m2.matchyear = m.matchyear
       ) as highest_margin 
from tblform_matches m
where some condtion;

此查询的索引为:tblform_matches(round, matchyear, score_diff),查找速度非常快。

编辑:

使用明确的join

可以获得更好的效果
SELECT m.*, m2.highest_margin
from tblform_matches m join
     (select MAX(ABS((m2.home_score - m2.away_score))) as highest_margin
      from tblform_matches m2
      group by year(m2.match_date), m2.round
     ) m2
     on year(m.match_date) = year(m2.match_date) and m2.round = m.round
where some condition;