2009-07-07 55 views
0

我希望你能帮助我解决这个问题。我收到了即将更新到公开测试版2的推特服务(http://foller.me),但我不想这样做,直到我可以在至少2或3秒内发布页面为止。目前的版本很简单,但我正在开发的开发版本非常复杂。寻找MySQL优化和微调技巧

这是关于我的关系和配置文件表都包含约200万行。配置文件表包含一般的twitter用户信息,关系表包含均在UNIQUE索引中的[twitter_idfollowed_by]条目。有一段时间运行的cron作业,并询问Twitter API有关用户关注者的信息,并将数据插入到关系数据库中。

我正在使用InnoDB,所以表未被锁定,但频繁更新,因此查询缓存没有获得足够的匹配,特别是在执行cron作业时。

我有类似SELECT screen_name FROM profiles WHERE twitter_id IN (SELECT followed_by FROM relations WHERE twitter_id = 'kovshenin')的陈述。我相信这不是一个很好的方法,当我打开它时,这些是mysql-slow日志中出现的那些(以及其他很多)。

无论如何,我需要一些关于如何为我的项目实现良好运行时的一般技巧。

非常感谢。

+0

我很乐意分享我们在发展TagCloud时发现的一些问题和解决方案。如果您想直接与我联系,请在2005年联系我。请访问http://blog.gahooa.com/about获取联系信息。 – gahooa 2009-07-07 14:22:21

回答

3

尝试重写你的查询,如下所示:

SELECT screen_name 
FROM profiles p 
WHERE EXISTS 
     (
     SELECT 1 
     FROM relations r 
     WHERE r.twitter_id = 'kovshenin' 
       AND r.followed_by = p.twitter_id 
     ) 

而且,因为你有一个UNIQUE指数,你将最有可能从此改写你的查询作为JOIN受益:

SELECT p.screen_name 
FROM relations r 
JOIN profiles p 
ON  p.twitter_id = r.followed_by 
WHERE r.twitter_id = 'kovshenin' 

您可能还可以通过使用经常使用的列来创建多个索引,从而牺牲额外的开销。

例如,这个查询:

SELECT p.screen_name 
FROM relations r 
JOIN profiles p 
ON  p.twitter_id = r.followed_by 
WHERE r.twitter_id = 'kovshenin' 

甚至不会考虑profiles,如果在profiles (twitter_id, screen_name)创建一个综合指数。

如果选择screen_name(也是唯一的screen_name,即它总是在SELECT列表中的唯一列)为您的应用程序很常见的查询时,您应考虑创建这样一个指数。

1

还要确保使用EXPLAIN命令行来检查查询在慢速查询日志

EXPLAIN SELECT * FROM PROFILES 

这会告诉你什么是减缓查询下(没有索引,无连接等),帮助调试较慢那些。您还可以查看this answer以获取有关MySQL事件探查器的信息,以便深入了解表锁,查询缓存检查/写入等问题。