3

我有一个电子商务 Rails 应用程序,出于报告原因,我们需要在其中输出客户在过去一年内在页面上下达的订单。现在,数据集非常大,在单个页面上显示这些订单需要相当多的 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 哈希):

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

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

例如,我将如何从 Redis 订单键中获取客户名称:

= REDIS.hget(order_key, "customer_name")
4

3 回答 3

2

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

  1. 对输出进行分页,但为未分页的输出提供 PDF 或 CSV。
  2. 简化您的视图逻辑......很多。
  3. 尝试像循环这样的帮助程序,而不是渲染复杂的表格或嵌套的部分。
  4. 使用 JSON 和 JavaScript 将您的渲染移至客户端。

就是这样,真的。如果其中一项或多项无法将您带到您需要去的地方,那么可能是时候重新审视您的要求了。

于 2012-06-15T07:24:36.503 回答
2

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

<% @orders.each do |order| %>
  <% cache ["v1", order] do %>
    <%= render order %>
  <% end %>
<% end %>
于 2012-06-15T07:59:49.323 回答
2

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

如果您需要交互式选择报告期间,则需要将请求排队并使用后台作业构建报告。

于 2012-06-15T08:46:13.580 回答