优化并改善此MYSQL查询的性能
SELECT u.id, u.honour, COUNT(*) + 1 AS rank
FROM user_info u
INNER JOIN user_info u2
ON u.honour < u2.honour
WHERE u.id = '$id'
AND u2.status = 'Alive'
AND u2.rank != '14'
此查询当前完全放慢了我的服务器速度。它根据你的荣誉得出你在“user_info”表中的等级,它将它存储在我们所有的用户之外。优化并改善此MYSQL查询的性能
解释的截图。
http://cl.ly/370z0v2Y3v2X1t1r1k2A
SELECT u.id, u.honour, COUNT(*)+1 as rank
FROM user_info u
USE INDEX (prestigeOptimiser)
INNER JOIN user_info u2
ON u.honour < u2.honour
WHERE u.id='3'
AND u2.status='Alive'
AND u2.rank!='14'
我认为负载来自您的连接条件'<'。
你可以尝试拆分你的查询或者(或者如果你更喜欢子查询),并使用荣誉指数计数。
SELECT id, honour INTO @uid, @uhonour
FROM user_info
WHERE id = '$id';
SELECT @uid, @uhonour, COUNT(honour) + 1 as rank
FROM user_info
WHERE status = 'Alive'
AND rank != '14'
AND @uhonour < honour;
首先,你应该让你的查询有意义添加group by
条款。其次,你应该改变状态列来保存一个整数,使索引更小。
第三,你要创建一个这样的ID和状况的指标:
alter table user_info add index idxID_Status (id, status)
最后,获得的行列,你应该看看这个answer。此外,您应该添加一种方式来订购它们......获得无秩序的排名并不是真正的排名。
您为什么认为查询没有意义?注意,有'WHERE u.id ='$ id'',所以它只有一个用户,因此只有一个组。 – 2012-04-13 17:04:34
@Shedal你有没有注意到没有分组,那里是一个聚合函数? – 2012-04-13 17:05:32
是的,我做到了。只需尝试一下简单的查询即可。计算所有选定的行确实是大卫试图在这种情况下实现的。 – 2012-04-13 17:06:26
从解释中可以看出,MySQL在这里使用了错误的索引。首先,删除所有索引并创建一个新索引,至少包含以下两个字段:Id
和Honour
。它应该大大提高性能。
ALTER TABLE user_info ADD INDEX myIndex (id, honour);
您可能需要添加一些索引 – 2012-04-13 17:00:19
您是否注意到您没有任何分组? – 2012-04-13 17:00:53
你可以包括从您的选择扩展解释 – ManseUK 2012-04-13 17:00:59