当数据库很小时,这个查询工作正常,但是现在数据库中有数百万行,我意识到我应该先看看优化它。它正在查看超过600,000行并且正在使用where;使用临时;使用filesort(导致执行时间为5-10秒)。它正在使用字段'battle_type。'上的索引。
SELECT username, SUM( outcome ) AS wins, COUNT( * ) - SUM( outcome ) AS losses
FROM tblBattleHistory
WHERE battle_type = '0' && outcome < '2'
GROUP BY username
ORDER BY wins DESC , losses ASC , username ASC
LIMIT 0 , 50
答案 0 :(得分:5)
您似乎需要username, battle_type, outcome
或username, outcome, battle_type
上的索引。
答案 1 :(得分:3)
首先要确保您拥有良好的索引(正如其他人所提到的那样)。
但是,看起来您正在为网页创建某种排行榜。我的第一个问题是 - 你真的需要实时执行这个查询吗?您可以在数据库中创建一个表(或在users表中添加一个胜负列),并使用此查询的结果并定期刷新它吗?
答案 2 :(得分:3)
让我们看看,你在做什么:
在第3步和第4步,你没有任何影响力。当前形式的第2步无法从任何索引中受益,因为outcome < 2
是范围条件,索引(battle_type,结果,用户名)看起来非常诱人。
假设outcome
是0,1,2,3...
的枚举,您可以将范围条件更改为相等比较并从索引上获益(battle_type,outcome,username):
SELECT username, SUM( outcome ) AS wins, COUNT( * ) - SUM( outcome ) AS losses
FROM tblBattleHistory
WHERE battle_type = 0 AND outcome IN (0, 1)
GROUP BY username
ORDER BY wins DESC , losses ASC , username ASC
LIMIT 0 , 50
如果outcome
不是枚举,那么(battle_type,outcome)的索引就可以了。因为battle_type
是复合索引中的前缀,所以(battle_type)上的索引现在只是过量。