2012-04-13 90 views
-1
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' 
+1

您可能需要添加一些索引 – 2012-04-13 17:00:19

+0

您是否注意到您没有任何分组? – 2012-04-13 17:00:53

+0

你可以包括从您的选择扩展解释 – ManseUK 2012-04-13 17:00:59

回答

1

我认为负载来自您的连接条件'<'。

你可以尝试拆分你的查询或者(或者如果你更喜欢子查询),并使用荣誉指数计数。

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; 
1

首先,你应该让你的查询有意义添加group by条款。其次,你应该改变状态列来保存一个整数,使索引更小。

第三,你要创建一个这样的ID和状况的指标:

alter table user_info add index idxID_Status (id, status) 

最后,获得的行列,你应该看看这个answer。此外,您应该添加一种方式来订购它们......获得无秩序的排名并不是真正的排名。

+0

您为什么认为查询没有意义?注意,有'WHERE u.id ='$ id'',所以它只有一个用户,因此只有一个组。 – 2012-04-13 17:04:34

+0

@Shedal你有没有注意到没有分组,那里是一个聚合函数? – 2012-04-13 17:05:32

+0

是的,我做到了。只需尝试一下简单的查询即可。计算所有选定的行确实是大卫试图在这种情况下实现的。 – 2012-04-13 17:06:26

1

从解释中可以看出,MySQL在这里使用了错误的索引。首先,删除所有索引并创建一个新索引,至少包含以下两个字段:IdHonour。它应该大大提高性能。

ALTER TABLE user_info ADD INDEX myIndex (id, honour); 
+0

这将如何影响依赖于其他索引的网站的其余部分?我可以有分组索引和单个索引吗? – David 2012-04-13 17:16:21

+0

哦,好的,我的建议有点匆忙,我只是把它当成一个实验。然后创建这个新的索引,不要丢弃任何东西。但是你可能需要提示MySQL使用正确的索引。 – 2012-04-13 17:17:35

+0

我该怎么做呢? – David 2012-04-13 17:19:41