帮助我优化具有太多属性的ActiveRecord对象

时间:2011-08-31 14:32:24

标签: mysql ruby-on-rails optimization activerecord

我正在开发一个与旧数据库绑定的应用程序。主要模型基于一个愚蠢的大型100+列表。我不太了解ActiveRecord的内部工作原理,但在我看来,这个模型上的任何请求都在减慢,因为它创建了具有100多个属性的对象。我们称之为SlowModel。

在我的开发计算机上使用此模型渲染页面有时需要17秒。直接查询mysql查询只需要0.5~1秒。

我设法通过使用选择字段子集(20左右)的MySQL视图来加速应用程序的一部分。我们称之为QuickModel。使用视图是可以的,但不是最便携的解决方案。

我可能会继续尝试将此QuickModel添加到网站的其他部分,但我想知道是否有人有其他想法加速原始对象。例如,有没有办法在模型中指定activerecord应该忽略哪些列并避免构建?也许有特定的列类型(:text ??)导致ActiveRecord对象膨胀。

假设列具有适当的索引。

3 个答案:

答案 0 :(得分:5)

您可以使用ActiveRecord查找的:select选项指定模型查找中返回的列:

SlowModel.all(:select => 'id, col1, col2, col3')

...将加载SlowModel的实例,只填充指定的列。

答案 1 :(得分:1)

如何拥有一个全新的QuickModel,它位于自己的表中......还有一个QuickModel has_one SlowModel?

您可以使用SQL将最必要的数据移动到QuickModel表中,并在必要时仅使用my_quick_model.slow_model引用SlowModel。

或者,您可以将“选择”添加到默认范围(您可以google“rails default scope”获取更多信息)。默认情况下,它只会获取缩小的集合 - 但您可以通过传递来请求所有属性:select => “*”如有必要。

答案 2 :(得分:1)

根据Winfield的说法,您可能需要查看使用SlimScrooge之类的属性跟踪器。跟踪器尝试仅获取您正在使用的数据,从而减少开销。它试图自动完成Winfield的建议。

自述文件中的示例:

# 1st request, sql is unchanged but columns accesses are recorded
Brochure Load SlimScrooged 1st time (27.1ms)   SELECT * FROM `brochures` WHERE (expires_at IS NULL)

# 2nd request, only fetch columns that were used the first time
Brochure Load SlimScrooged (4.5ms)   SELECT `brochures`.expires_at,`brochures`.operator_id,`brochures`.id FROM `brochures` WHERE (expires_at IS NULL)

# 2nd request, later in code we need another column which causes a reload of all remaining columns
Brochure Reload SlimScrooged (0.6ms) `brochures`.name,`brochures`.comment,`brochures`.image_height,`brochures`.id, `brochures`.tel,`brochures`.long_comment,`brochures`.image_name,`brochures`.image_width FROM `brochures` WHERE `brochures`.id IN ('5646','5476','4562','3456','4567','7355')

# 3rd request
Brochure Load SlimScrooged (4.5ms)   SELECT `brochures`.expires_at,`brochures`.operator_id,`brochures`.name, `brochures`.id FROM `brochures` WHERE (expires_at IS NULL)