繁体   English   中英

如何优化这个MySQL查询

[英]How to optimize this MySQL query

当数据库很小时,这个查询工作正常,但是现在数据库中有数百万行,我意识到我应该先考虑优化它。 它正在查看超过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

您似乎需要有关username, battle_type, outcomeusername, outcome, battle_type

首先要确保你有好的指数(正如其他人提到的那样)。

但是,看起来您正在为网页创建某种排行榜。 我的第一个问题是 - 你真的需要实时执行这个查询吗? 您可以在数据库中创建一个表(或在users表中添加一个胜负列),并使用此查询的结果并定期刷新它吗?

让我们看看,你在做什么:

  1. 查找battle_type = 0且结果<2的行
  2. 按用户名排序以进行分组
  3. 计算聚合并将行折叠到不同的用户名
  4. 通过dinamically计算的字段排序

在第3步和第4步,你没有任何影响力。 当前形式的第2步不能从任何指数中受益,因为outcome < 2是范围条件,指数(battle_type,结果,用户名)看起来非常诱人。

假设outcome0,1,2,3...枚举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)上的索引现在只是过量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM