我正在开发一个与旧数据库绑定的应用程序。主要模型基于一个愚蠢的大型100+列表。我不太了解ActiveRecord的内部工作原理,但在我看来,这个模型上的任何请求都在减慢,因为它创建了具有100多个属性的对象。我们称之为SlowModel。
在我的开发计算机上使用此模型渲染页面有时需要17秒。直接查询mysql查询只需要0.5~1秒。
我设法通过使用选择字段子集(20左右)的MySQL视图来加速应用程序的一部分。我们称之为QuickModel。使用视图是可以的,但不是最便携的解决方案。
我可能会继续尝试将此QuickModel添加到网站的其他部分,但我想知道是否有人有其他想法加速原始对象。例如,有没有办法在模型中指定activerecord应该忽略哪些列并避免构建?也许有特定的列类型(:text ??)导致ActiveRecord对象膨胀。
假设列具有适当的索引。
答案 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)