【问题标题】:What's the difference between “includes” and “preload” in an ActiveRecord query?ActiveRecord 查询中的“包含”和“预加载”有什么区别?
【发布时间】:2012-08-14 05:38:48
【问题描述】:

我正在努力寻找 ActiveRecord 对象的 include() 和 preload() 的比较。谁能解释一下区别?

【问题讨论】:

    标签: ruby-on-rails ruby activerecord


    【解决方案1】:

    Rails 有两种方法可以避免 n+1 问题。一个涉及创建一个基于大连接的查询来拉入您的关联,另一个涉及为每个关联创建一个单独的查询。

    当您执行includes 时,rails 决定为您使用哪种策略。它默认为单独的查询方法(预加载),除非它认为您正在使用您的条件或顺序中的关联列。因为这只适用于连接方法,所以它使用它。

    Rails 的启发式方法有时会出错,或者您可能有特定原因偏爱一种方法而不是另一种方法。 preload(及其配套方法eager_load)允许您指定您希望rails 使用的策略。

    【讨论】:

    【解决方案2】:

    详细了解请参考this博客。

    简而言之:

    Preload 在单独的查询中加载关联数据。

    User.preload(:posts).to_a
    
    # => SELECT "users".* FROM "users" SELECT "posts".* FROM "posts"  WHERE "posts"."user_id" IN (1)
    

    包含在单独的查询中加载关联数据,就像 预载。但是它比preload更智能。但在某些情况下,它会结合查询。

    包含如何更智能?

    我们不能在 where 条件下使用 post 表。以下查询将导致错误。

    User.preload(:posts).where("posts.desc='ruby is awesome'")
    
    # =>
    SQLite3::SQLException: no such column: posts.desc:
    SELECT "users".* FROM "users"  WHERE (posts.desc='ruby is awesome')
    

    但是我们可以在where查询中使用post表include

    User.includes(:posts).where('posts.desc = "ruby is awesome"').to_a
    
    # =>
    SELECT "users"."id" AS t0_r0, "users"."name" AS t0_r1, "posts"."id" AS t1_r0,
           "posts"."title" AS t1_r1,
           "posts"."user_id" AS t1_r2, "posts"."desc" AS t1_r3
    FROM "users" LEFT OUTER JOIN "posts" ON "posts"."user_id" = "users"."id"
    WHERE (posts.desc = "ruby is awesome")
    

    如您所见,包括从使用两个单独的查询切换到创建单个 LEFT OUTER JOIN 来获取数据。它还应用了提供的条件。

    【讨论】:

      【解决方案3】:

      正如 apidoc 所说,“此方法已被弃用或在最新的稳定版本上移动。此处显示了最新的现有版本 (v3.0.9)。”所以不同之处在于只包括不弃用。

      【讨论】:

      • '已弃用或移动'。在这种情况下,它已被移动,而不是被弃用。而且它们不一样。
      • 抱歉,但如果我有可能调用它(Rails 3.2.6),它不会为我移动 - 只是已弃用。
      • 当人们将代码从一个模块重构到另一个模块时,apidoc 会变得非常混乱——它可以认为一个方法甚至从公共 api 的角度来看已经通过了它没有
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-16
      • 2021-10-02
      • 1970-01-01
      • 1970-01-01
      • 2023-03-05
      • 2013-03-01
      相关资源
      最近更新 更多