为什么这个查询真的很慢,有70k +行?

时间:2016-03-16 22:08:23

标签: mysql

首先,这是我的表结构:

CREATE TABLE IF NOT EXISTS `site_forum_comments` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`forum_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`data` int(11) NOT NULL,
`comment` longtext NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

在导入我的备份之前,它有10-15行,我根据评论数量建立了一个排名系统,这个查询运行得很完美:

SELECT u.id, u.username, COUNT(f.id) AS rank 
FROM site_users AS u 
LEFT JOIN site_forum_comments AS f ON (f.user_id = u.id)
GROUP BY u.id 
ORDER BY rank DESC 
LIMIT :l

但是现在,插入了超过70,000行,脚本甚至无法加载,只会崩溃服务器。

我可能做错了什么?这是关于查询的问题还是表结构?

提前致谢,欢呼!

2 个答案:

答案 0 :(得分:0)

这是您的查询:

SELECT u.id, u.username, COUNT(f.id) AS rank 
FROM site_users u LEFT JOIN
     site_forum_comments f
     ON f.user_id = u.id
GROUP BY u.id 
ORDER BY rank DESC 
LIMIT :l

因为您选择排名最高的用户,所以您可以使用内部联接而不是外部联接。无论如何,这个版本没有很多优化机会。但是,您需要site_forum_comments(user_id, id)上的索引。

使用相同的索引和相关的子查询可能会获得更好的性能:

SELECT u.id, u.username, 
       (SELECT COUNT(*)
        FROM site_forum_comments f
        WHERE f.user_id = u.id
       ) as rank
FROM site_users u 
ORDER BY rank DESC 
LIMIT :l;

答案 1 :(得分:0)

您目前正在将所有用户加入到他们的评论中,而user_id列上的索引没有变慢。

以下查询将首先选择最高用户,并且仅使用site_users表(使用索引超过site_users.id)加入具有最高排名的一个用户。所以它应该更快。

SELECT site_users.id, site_users.username, a.rank
FROM (
    SELECT user_id, COUNT(*) as rank
    FROM site_forum_comments
    GROUP BY user_id 
    ORDER BY rank DESC
    LIMIT 1
) AS a 
LEFT JOIN site_users ON a.user_id = site_users.id

请注意,使用此查询,如果排名为0,则无法获得结果