如何基准和优化真正的数据库密集型Rails操作?

问题描述:

客户端网站的管理部分有一个动作,例如Admin :: Analytics(我没有构建但必须维护),它通过执行几十个相当密集的数据库查询来编译网站使用情况分析。无论何时编译分析报告,此功能一直是应用程序性能的瓶颈。但是,最近这个瓶颈变得非常糟糕,以至于当访问时,站点会停下来并且无限期地挂起。直到昨天,我从来没有理由在服务器上运行“top”命令,但是这样做后,我意识到Admin :: Analytics#索引会导致mysqld在四核上高于350 +%的CPU功率,生产VPS。如何基准和优化真正的数据库密集型Rails操作?

我已下载生产数据和生产日志的新副本。但是,当我在开发框中本地访问Admin :: Analytics#索引时,使用生产数据时,它会在大约10 - 12秒内加载(并使用我的双核CPU的〜150 +%),这很不正常。我猜想可能会在突然出现的mysql设置中出现差异。此外,数据库的mysqldump现在是531 MB,而28天前它只有336 MB。无论如何,我在VPS上没有root访问权限,因此调整mysqld的性能会很麻烦,而且我真的很想知道这个问题的确切原因。但是,生产日志不包含信息。在查询上;他们只是报告了这些请求所花费的时间长度,平均每个分钟需要几分钟(尽管它们似乎导致mysqld拖延了很长的时间,并促使我要求我们的主机重新启动mysqld,以便让我们的站点备份在一个例子中)。

我想我可以尝试提高生产中的日志级别以征求信息。关于由Admin :: Analytics#index执行的数据库查询,但同时我害怕在生产中复制此行为,因为我不想调用我们的主机重新启动mysqld!此操作在其控制器中包含单个数据库请求,并在其视图中嵌入了几十条准备好的语句!

您将如何进行基准测试/诊断和优化/修复此操作?

(题外话:很显然,我想完全取代与谷歌Analytics(分析)或类似的解决方案这一功能,但我需要继续之前解决这个问题。)

+1

您使用InnoDB或MyISAM的存储引擎是哪个? InnoDB使用行级别的表锁,当你的大型查询运行时,它应该允许你的其他查询仍然工作。 MyISAM使用表级锁,这似乎是你的查询发生的事情。你对这个从其他页面插入的统计表做了一个大的查询,而这个大的查询正在运行,其余的网站将锁定,直到查询完成,如果你在MyISAM – 2010-07-30 20:00:16

+0

乔纳森, 伟大的领导。我不确定,但是运行“展示引擎”在mysql中显示MyISAM显然被设置为“DEFAULT”,而InnoDB(和其他3个引擎)显然被支持。你知道如何确定这一点吗?到目前为止,我的谷歌搜索几乎没有帮助... – 2010-07-30 21:53:33

+0

看看应用程序生成的SQL语句。这可能会让人大开眼界某些ActiveRecord生成的查询可能会很糟糕。你可能需要识别一些需要手动操作的东西。 – seand 2010-07-31 18:18:26

我建议考虑看看这篇文章: http://axonflux.com/building-and-scaling-a-startup

特别是query_reviewer和newrelic对我来说是一个救命的人。

我非常感谢所有的帮助,但最终解决的办法是在Analytics表上实现几个索引以迎合此操作中的查询。一个简单的Rails迁移来添加索引和动作现在可以在我的开发盒和产品上不到一秒钟加载!

+0

我仍然会推荐我在建筑/比例上提出的文章。 query_reviewer插件非常适合帮助您找到缺失的索引并正确实施它们。我知道你的问题已经解决,但我想在这里为任何可能寻求帮助的人添加这个 – Ryan 2010-08-30 20:17:57