我有足球比赛列表。它有像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的新蜜蜂
提前致谢。
答案 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;