优化数据库查询Rails

时间:2014-12-22 17:21:26

标签: sql ruby-on-rails json database activerecord

所以我正在和我的几个朋友一起开发一个Rails端项目,需要加载很多种子数据。我在JSON文档中有种子数据,该文档现在包含不到3200个JSON对象,每个对象具有相同的3个字段名称。

我已经在Rails中解析并播种了这些数据,为每个JSON对象创建了一条新记录。我应该注意到该对象有一些has_many关联。

问题是,在我使用JSON文件播种数据库之后,当我尝试将所有3200条记录加载到页面中时(仅使用普通的ModelName.all.each块),加载时间非常荒谬......约17826ms(17.8秒)。

根据控制台,它说(Views: 16252.4ms | ActiveRecord 1522.9ms)。我已经考虑过实施预先加载和预加载(我还在努力)。

我的问题是,如何进一步优化?我已经尝试ModelName.preload(:associationName)进行预加载,但这似乎并没有改变回复时间(也许我做错了)。令我难以置信的是,3200记录不是很多......为什么这么长时间?在项目早期,将像Redis这样更快的东西加入是一个可行的选择吗?

3 个答案:

答案 0 :(得分:2)

您可能遇到n+1问题,确定您获取控制器中的所有对象,但在视图中您正在访问需要额外延迟查询的某些关系,以修复您需要急切加载整个数据,使用includes关键字

@all_objects_with_associations = SomeObject.includes(:some_association).all

另一个额外的级别是使用片段缓存,假设你不想分页(如果你使用的是rails 4默认启用),你需要做的就是在模板的顶部添加一个缓存块,以及您认为如果更改

则需要缓存失效的所有变量
cache @all_objects_with_associations do

要获取更多信息,请查看以下链接

Eager loading in rails
Fragment caching in rails

答案 1 :(得分:1)

这是真正杀死速度的观点。渲染许多物体当然需要时间。您应该对数据进行分页并一次显示有限数量的数据。这将消除数据库和视图的压力。

使用“will_paginate”进行分页。

或者,您可以实现“垂直分页”,即在页面向下滚动到底部以进行AJAX调用以获取并附加更多结果。

此外,我将查看视图并确保不通过它进行数据库查询。如果是的话,我会尝试通过急切加载来消除它们,或者以某种方式将它们移动到控制器,即将数据发送到视图而不是让视图获取数据。

答案 2 :(得分:1)

除了分页,您只能从数据库中获取必需的字段,这将进一步提高您的性能。

由于您的观看次数很多,请考虑以下因素:

  • 使用partials,helper方法(以简化视图逻辑)
  • 将渲染移动到客户端(从服务器端发送JSON)
  • 添加缓存策略

如果您可以发布有关您观看次数的详细信息,则可以帮助我们提供更多自定义帮助。