【问题标题】:Avoiding lazy loading in Datamapper in loop避免循环中 Datamapper 中的延迟加载
【发布时间】:2013-09-11 12:21:27
【问题描述】:

我是 Ruby on Rails 和 Datamapper 的新手。我使用 Datamapper 编写了模型,我的模型名称之一是 Student。在一个视图 haml 文件中,我编写了以下代码:

-students = Student.all
-students.each |student|
 %tr
  %td= student.roll_no 
  %td= student.type if student.type
  %td= student.department.name

在这里,我使用 newrelic -rpm 来分析我的代码。在这里,我发现在上述块的每次迭代中,都会生成一个select prop1, prop2,... from students where id ="some value" 形式的查询。这是非常不希望的,因为块的每次迭代都需要时间。我认为这是由于延迟加载。我已经花了将近一个星期的时间,但没有发现可以避免这种情况。如果有人对此有任何想法,请帮助我。谢谢你。

【问题讨论】:

  • 你能添加你传递给每个的块吗?

标签: ruby-on-rails lazy-loading ruby-datamapper


【解决方案1】:

如果您可以向我们展示app/db/schema.rb 中的Students 表的架构,将会很有帮助。

我怀疑您的问题不是因为对学生中每一行的懒惰评估而导致学生的每次迭代都需要很长时间,而是它必须在每个步骤中加载部门。 Student.all 是,自 Rails 4 以来,懒惰地评估,但它一次加载 the 整个集合。

为了解决您的问题,您必须在第一行写上Student.includes(:department)

【讨论】:

  • 我认为,您建议的方法适用于 Activerecord。但是这里我使用的是Datamapper,这里在app目录中没有带有schema.rb的db文件夹。如果我错了,请纠正。我没有使用 Rails 4,我的 Rails 版本是 3。
【解决方案2】:

您可以强制 DataMapper 在开始循环之前预加载数据。

将Collection加载到students后,添加一行如:

prefetch = students.collect { |s| s.department }

您不必对prefetch 对象做任何事情; DataMapper 将加载所有数据并将其与students 对象相关联。然后您应该发现您可以按预期迭代循环,而无需为每个循环生成单独的查询。 (我刚刚在我正在做的一个项目上对此进行了测试,它成功了。)

【讨论】:

    猜你喜欢
    • 2012-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-27
    • 2015-10-06
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    相关资源
    最近更新 更多