代码之家  ›  专栏  ›  技术社区  ›  nonopolarity

rubyonrails“has\ many”数组是否在“需要知道”的基础上提供数据?

  •  0
  • nonopolarity  · 技术社区  · 14 年前

    比如说,在rubyonrails上,如果Actor模型对象是tomhanks,“has\u many”fans是20000个Fan对象,那么

    actor.fans
    

    给出一个包含20000个元素的数组。可能,元素没有预先填充值?否则,从数据库获取每个Actor对象可能非常耗时。

    那么,当我访问actor.fans[500]时它是否拉取数据,当我访问actor.fans[0]时它是否拉取数据?如果它从一个记录跳到另一个记录,那么它就无法通过顺序读取来优化性能,这样在硬盘上的读取速度会更快,因为这些记录可能在附近的扇区/盘片层——例如,如果程序接触到2个随机元素,那么只读取这2个记录会更快,但是,如果它以随机顺序接触所有元素,那么以顺序方式读取所有记录,然后处理随机元素可能会更快。但是RoR怎么知道我是在做一些随机的元素,还是在做所有随机的元素呢?

    2 回复  |  直到 14 年前
        1
  •  1
  •   Tadas T    14 年前

    如果你只使用其中的2条记录,为什么你要取出50000条记录?那就只从DB拿这两个。如果您想列出风扇,那么您可能会使用分页-即在查询中使用limit和offset,或者一些分页gem(如将分页)。

    我看不出有什么合乎逻辑的解释你为什么要这样做。解释一个真实的情况以便我们能帮助你。

    Actor.all(:include => :fans)
    

    这将立即加载所有的fans,因此只有2个查询,而不是N+1,其中N是参与者的数量

        2
  •  1
  •   stephenr    14 年前

    看看服务器在开发模式下输出的SQL,它会告诉您加载了多少个fan记录。在这种情况下 actor.fans 确实会导致它们全部加载,这可能不是您想要的。

    您有几种选择:

    • 按照塔达斯的建议使用分页器;
    • 与fans表建立另一个关联,只吸引你感兴趣的人。这可以通过has\u many语句中的条件来实现,例如。
      has_many :fans, :conditions => "country of residence = 'UK'"
    • :finder_sql 选项
    • 指定 :limit 选项,它将限制返回的行数。