我正在编写一个Web应用程序来监控家具厂的生产流程.它有数千个数据需要处理.到目前为止,我在Mongrel + MySQL上运行RoR并且它真的很慢(对于某些视图为2-4分钟).当我查看RoR日志时,似乎数据库查询不是很慢(0-10ms).
RoR在将数据库数据转换为对象时是否会变慢?杂种慢吗?
编辑:第一件事:我在开发中.ENV.在生产环境中,最慢的视图需要2分钟(在好的计算机上会减少不到1分钟,我的是5年).使用ruby-prof和一些常识,我发现哪些方法正在减慢应用程序的速度.问题是在大型数据集的循环中调用单个SQL查询:
ofs = Ofkb.find_by_sql ["..some large sql query..."] for of in ofs # About 700-1000 elements ops = Operation.find(..the single query..) etc. end
以下是这些方法的ruby-prof结果:
%self total self wait child calls name 32.19 97.91 97.91 0.00 0.00 55 IO#gets (ruby_runtime:0} 28.31 86.39 86.08 0.00 0.32 32128 Mysql#query (ruby_runtime:0} 6.14 18.66 18.66 0.00 0.00 12432 IO#write (ruby_runtime:0} 0.80 2.53 2.42 0.00 0.11 32122 Mysql::Result#each_hash (ruby_runtime:0}
问题是:我无法真正避免那些单一的查询.我有数以千计的事件,我必须从中计算复杂的数据.现在我在那些方法上使用memcached,除非你是第一个请求页面的人.
我会同意其他人的意见.你必须剖析.在您知道具体导致缓慢的原因之前,对代码执行任何操作都没有意义.试图在不了解原因的情况下解决问题,就像感觉不舒服,并决定在感觉好转之前进行大量手术.首先诊断您的问题.它可能像网络设置一样小,也可能是代码中的一条坏线.
分析的一些提示:
如何配置您的Rails应用程序
性能测试Rails应用程序
Forge - Profiling Rails应用程序
一旦找到瓶颈,你就可以弄明白该怎么做了.
我推荐这些视频: Railslab Scaling Rails
现在根据教授结果进行修订:
好.现在您可以看到您的问题是您正在使用基于循环查看另一个活动记录查询结果的查询进行某种计算,我建议您研究构建一个自定义SQL语句,结合您的初始选择标准和获得你需要的循环计算.您可以通过优化SQL来加快速度.
每个视图访问执行的0-10ms查询中有多少个?您的数据模型的哪些部分被引用?您是否正在使用:include以获得对您的关联的热切加载?
Rails和你做的一样慢.随着理解来速度(通常!)
扩展上面的内容,你是否有has_many关联,特别是你的视图引用了"很多"的一面没有:include
?这会导致您find(:all)
在主表上执行与细节的连接 - 如果您有大量的详细记录并且正在单独处理所有这些,这可能会变得昂贵.
像这样的东西:
Master.find(:all, :include => :details)
...可能有帮助.但仍然从稀疏信息中猜测.
有一个老Railscast关于这个问题在这里
虽然RnR 的声誉很慢,但这听起来太极端了,不能成为语言的一个简单问题.
您应该运行一个分析器来确定哪些功能很慢以及为什么.减慢Web应用程序最常见的是" n + 1问题 ".也就是说,当您的数据库中有n个数据项时,该应用程序会对数据库进行单独的查询,而不是生成一个获取它们的查询.但是在运行探查器之前你无法知道.ruby-prof是我用过的一个分析器.
根据个人资料结果编辑编辑:
我坚信你总能删除一个查询循环.正如Mike Woodhouse所说,Rails的方法是使用has_many或其他关联来指定表之间的关系,然后让rails自动生成表连接,这是明确的,快速的和"Rails方式".但是如果你刚开始使用裸SQL,或者在这种情况下关联不起作用,你可以自己生成适当的连接.如果所有其他方法都失败了,您可以创建一个视图或非规范化表,其中包含先前通过循环找到的结果.实际上,您必须遍历生成的查询这一事实可能表明您的表设计本身存在一些缺陷.
总而言之,如果缓存您的查询结果对您来说效果很好,那么请坚持下去.在需要时进行优化.