[英]Some Serious SQL Query Optimization Needed (MySQL)
这是我当前的查询:
SELECT IFNULL(sum(open_for), 0) total, count(IF(open_for > 0, 1, null)) wins, count(IF(open_for < 0, 1, null)) losses FROM `sport_points` WHERE (sportable_id = 1 and sportable_type = 'Team' and game_time > '2010-07-13 11:39:58 UTC'
它基本上返回以下聚合数据:
团队A
现在,假设表中还有大约6个其他列,我需要执行单独的查询来获取一个团队的所有特定于列的聚合数据。 例如:
SELECT IFNULL(sum(FINAL_FOR), 0) total, count(IF(open_for > 0, 1, null)) wins, count(IF(open_for < 0, 1, null)) losses FROM `sport_points` WHERE (sportable_id = 1 and sportable_type = 'Team' and game_time > '2010-07-13 11:39:58 UTC'
团队A
这种方法的问题在于,我必须为200多个团队中的所有列运行大约6个单独的查询。 这是一个严重的负载问题。
理想情况下,该查询将在一个查询中返回一个团队的所有特定于列的聚合数据。 结果看起来像这样:
团队A
...等等...
只是为了那些想要帮助的人的利益:
查询1:
SELECT
IFNULL(sum(open_for), 0) total
,COUNT(IF(open_for > 0, 1, null)) wins
,COUNT(IF(open_for < 0, 1, null)) losses
FROM
`sport_points`
WHERE
sportable_id = 1
AND sportable_type = 'Team'
AND game_time > '2010-07-13 11:39:58 UTC'
查询2:
SELECT
IFNULL(SUM(FINAL_FOR), 0) total
,COUNT(IF(open_for > 0, 1, null)) wins
,COUNT(IF(open_for < 0, 1, null)) losses
FROM
`sport_points`
WHERE
sportable_id = 1
AND sportable_type = 'Team'
AND game_time > '2010-07-13 11:39:58 UTC'
所需的输出列:团队名称,typeofquery,值
其中typeofquery是以下之一:
从两列open_for
和final_for
以及wins
和losses
列中派生。
最初考虑问题时,我猜测中间表可能有助于使用GROUP BY
子句进行处理。
例如
INSERT INTO
temptable
SELECT
teamname
,'open_for' type
,IFNULL(SUM(open_for), 0) total
,COUNT(IF(open_for > 0, 1, null)) wins
,COUNT(IF(open_for < 0, 1, null)) losses
FROM
`sport_points`
WHERE
sportable_id = 1
AND sportable_type = 'Team'
AND game_time > '...'
GROUP BY
teamname
然后运行相同的查询,但求和final_for
。 现在,您的临时表包含如下行:
teamname, type, total, wins, losses
TEAM A, open_for, 100, 37, 63
TEAM A, final_for, 30, 10, 20
TEAM B, open_for, 12, 8, 4
TEAM B, final_for, 50, 49, 1
您的最终查询可以根据需要连接列。
我会将其作为单个查询来执行,该查询针对每个统计信息返回单独的列 。 然后,如有必要,我将在我的应用程序代码中重组结果。 查询如下所示:
select teamname,
sum(open_for) as open_total,
count(if(open_for > 0, 1, null)) as open_wins,
count(if(open_for < 0, 1, null)) as open_losses,
sum(final_for) as final_total,
count(if(final_for > 0, 1, null)) as final_wins,
count(if(final_for < 0, 1, null)) as final_losses,
from sport_points
where sportable_id = 1
and sportable_type = 'Team'
and game_time > '...'
group by teamname
我建议这是一种更正统的关系方法,因此可以很容易地用SQL表示。 如果不是您的应用程序所需要的,那么进行调整的地方就是代码,它比SQL灵活得多。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.