提高rails视图渲染的性能

时间:2012-06-15 00:25:56

标签: ruby-on-rails ruby views redis scalability

我有一个电子商务Rails应用程序,出于报告原因,我们需要在过去一年内在一个页面上输出客户订购的订单。现在,数据集非常大,在单个页面上显示这些Orders需要相当多的SQL处理。这项任务最初非常缓慢,因此我将所有必需的订单详细信息移至Redis服务器,并且现在获取数据的速度非常快,但我们仍然没有完全实现。

以下是我们所拥有的:

Rendered **path**/sales_orders.html.haml within layouts/admin (39421.1ms)
Completed 200 OK in 44925ms (Views: 39406.8ms | ActiveRecord: 417.2ms)

该应用程序托管在Heroku上,如果请求超过30秒,则会被杀死。如你所见,我们远远高于这个限制。渲染视图时大部分时间都丢失了。

该页面包含一个日期过滤器,用户可在其中选择日期范围以从中选择订单。因此,缓存不是理想的解决方案,因为日期范围可能每次都会改变。

任何想法如何做到这一点?

Redis键具有以下格式(以下是Redis Hash):

orders:2012-01-01:123
orders:yyyy-mm-dd:$order-id

用户只需提供日期范围,我就可以获得订单命名空间下该日期范围内的所有密钥。

以下是我从Redis订单密钥获取客户名称的方法:

= REDIS.hget(order_key, "customer_name")

3 个答案:

答案 0 :(得分:2)

几乎所有的时间都花在渲染视图上。这可能意味着你有很多局部或其他复杂的视图逻辑。您的一些选择是:

  1. 分页您的输出,但提供PDF或CSV以进行取消标记输出。
  2. 简化您的视图逻辑......很多。
  3. 尝试像循环一样的助手,而不是渲染复杂的表或嵌套的部分。
  4. 使用JSON和JavaScript将渲染移​​动到客户端。
  5. 这就是它,真的。如果其中一个或多个不能满足您的需求,可能需要重新审视您的要求。

答案 1 :(得分:2)

我建议你使用片段缓存。读取片段的速度非常快(约0.5毫秒),根据我的经验,您不会一次又一次地重新渲染部分片段,从而获得巨大的加速增益。它也是一个相当便宜的解决方案,因为Rails负责使片段无效(如果您将模型用作缓存键的一部分),并且它需要对模板进行最少的更改。即解决方案可以简单:

<% @orders.each do |order| %>
  <% cache ["v1", order] do %>
    <%= render order %>
  <% end %>
<% end %>

答案 2 :(得分:2)

使用Heroku Scheduler插件考虑使用定期任务构建报告。 只要最后一刻的订单不需要包含在报告中,您就可以每晚制作报告并立即下载,以便用早晨咖啡阅读,或者甚至将它们邮寄给您(或者需要阅读的人)它们。)

如果您需要交互式选择报告的期间,则需要将请求排队并使用background jobs生成报告。