首先,这是我的表结构:
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行,脚本甚至无法加载,只会崩溃服务器。
我可能做错了什么?这是关于查询的问题还是表结构?
提前致谢,欢呼!
答案 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,则无法获得结果