如何在左连接中使用子查询时优化查询
问题描述:
表格: 请在此处查看以查看表格。 How to query counting specific wins of team and find the winner of the series如何在左连接中使用子查询时优化查询
问题:
- 如何让更多的查询优化?
- 如何减少查询冗余?
- 如何使此查询更快?
摘要
正如你可以在这个查询例子这一部分是多次使用看看。
WHERE leagueid = 2096
AND start_time >= 1415938900
AND ((matches.radiant_team_id= 1848158 AND matches.dire_team_id= 15)
OR (matches.radiant_team_id= 15 AND matches.dire_team_id= 1848158))
SELECT matches.radiant_team_id,
matches.dire_team_id,
matches.radiant_name,
matches.dire_name,
TA.Count AS teamA,
TB.Count AS teamB,
TA.Count + TB.Count AS total_matches,
SUM(TA.wins),
SUM(TB.wins),
(CASE
WHEN series_type = 0 THEN 1
WHEN series_type = 1 THEN 2
WHEN series_type = 2 THEN 3
END) AS wins_goal
FROM matches
LEFT JOIN
(SELECT radiant_team_id,
COUNT(id) AS COUNT,
CASE
WHEN matches.radiant_team_id = radiant_team_id && radiant_win = 1 THEN 1
END AS wins
FROM matches
WHERE leagueid = 2096
AND start_time >= 1415938900
AND ((matches.radiant_team_id= 1848158
AND matches.dire_team_id= 15)
OR (matches.radiant_team_id= 15
AND matches.dire_team_id= 1848158))
GROUP BY radiant_team_id) AS TA ON TA.radiant_team_id = matches.radiant_team_id
LEFT JOIN
(SELECT dire_team_id,
COUNT(id) AS COUNT,
CASE
WHEN matches.dire_team_id = dire_team_id && radiant_win = 0 THEN 1
END AS wins
FROM matches
WHERE leagueid = 2096
AND start_time >= 1415938900
AND ((matches.radiant_team_id= 1848158
AND matches.dire_team_id= 15)
OR (matches.radiant_team_id= 15
AND matches.dire_team_id= 1848158))
GROUP BY dire_team_id) AS TB ON TB.dire_team_id = matches.dire_team_id
WHERE leagueid = 2096
AND start_time >= 1415938900
AND ((matches.radiant_team_id= 1848158
AND matches.dire_team_id= 15)
OR (matches.radiant_team_id= 15
AND matches.dire_team_id= 1848158))
GROUP BY series_id
计划匹配
ID| leagueid| team_a_id| team_b_id| starttime
1| 2096| 1848158| 15| 1415938900
答
我相信这可以在没有子查询的情况下完成。
我提出了以下的匹配表
,并用于下面的查询分组的结果,每系列
SELECT
matches.leagueid,
matches.series_id,
matches.series_type,
COUNT(id) as matches,
IF(radiant_team_id=1848158,radiant_name, dire_name) AS teamA,
IF(radiant_team_id=1848158,dire_name, radiant_name) AS teamB,
SUM(CASE
WHEN radiant_team_id=1848158 AND radiant_win=1 THEN 1
WHEN dire_team_id=1848158 AND radiant_win=0 THEN 1
ELSE 0 END) AS teamAwin,
SUM(CASE
WHEN radiant_team_id=15 AND radiant_win=1 THEN 1
WHEN dire_team_id=15 AND radiant_win=0 THEN 1
ELSE 0 END) AS teamBwin
FROM `matches`
WHERE leagueid = 2096
AND start_time >= 1415938900
AND dire_team_id IN (15, 1848158)
AND radiant_team_id IN (15, 1848158)
group by leagueid,series_id,series_type,teamA,teamB
一个线,其产生以下结果
请注意,将一个系列的结果进行分组时,并不存在辐射团队或可怕团队等。在同一系列赛中,角色和角色可能会被切换多次,所以我只将队名称为teamA和teamB。
现在,看看你之前的问题,我发现你需要根据系列类型和每支球队的胜利来确定系列赛冠军。这将需要包装以前的查询并将其用作子查询,如
SELECT matchresults.*,
CASE series_type
WHEN 0 then IF(teamAwin>=1, teamA,teamB)
WHEN 1 then IF(teamAwin>=2, teamA,teamB)
ELSE IF(teamAwin>=3, teamA,teamB)
END as winner
from (THE_MAIN_QUERY) as matchresults
答
可能有更有效的方式得到你想要的结果。但是,为了使这个查询更有效率,您可以添加索引。这是多次where
条款:
WHERE leagueid = 2096 AND
start_time >= 1415938900 AND
((matches.radiant_team_id= 1848158 AND matches.dire_team_id= 15) OR
(matches.radiant_team_id= 15 AND matches.dire_team_id= 1848158))
条件与or
是很难优化。以下指数将有所帮助:matches(leagueid, start_time)
。覆盖指数(至少为where
条件)为matches(leagueid, start_time, radiant_team_id, dire_team_id)
。我会从后面的索引开始,看看它是否能够提高性能,足以满足您的需求。
WOOOOOOOOOOH。而已。你是最好的。非常感谢你 。这个问题是1周老〜〜/〜然后在最后。你解决了它:D非常感谢! – ronscript 2014-11-24 00:55:07
我有问题。如果我想使radiant_team_id和dire_team_id动态,该怎么办?例如我不想过滤出使用团队ID。 – ronscript 2014-11-24 01:16:29
这取决于。一系列确定了一个独特的团队对?或者它确实解决了可以应用于多个团队对的阶段?除此之外,您需要考虑模型层面有多少逻辑,以及可以使用业务逻辑来管理多少逻辑。 – amenadiel 2014-11-24 01:23:10