Ruby on Rails - 按子属性排序时出现 N + 1 问题



以下查询遇到为每条记录加载每个订单的"n+1"问题:

Job.joins('LEFT JOIN orders ON orders.job_id = jobs.id').order("orders.featured")

与此相同:

Job.includes(:order).order("orders.featured")

删除.order(…(部分会删除n+1问题,但它不会被排序。有什么办法解决这个问题吗?是否需要在父级中为"featured"属性创建一列?

输出:

  Order Load (0.4ms)  SELECT  "orders".* FROM "orders" WHERE "orders"."job_id" = $1 LIMIT 1  [["job_id", 26]]
  Rendered jobs/_job.html.erb (1.9ms)
  Order Load (0.3ms)  SELECT  "orders".* FROM "orders" WHERE "orders"."job_id" = $1 LIMIT 1  [["job_id", 3]]
  Rendered jobs/_job.html.erb (2.0ms)
  Order Load (0.3ms)  SELECT  "orders".* FROM "orders" WHERE "orders"."job_id" = $1 LIMIT 1  [["job_id", 52]]
  Rendered jobs/_job.html.erb (1.7ms)
  Order Load (0.3ms)  SELECT  "orders".* FROM "orders" WHERE "orders"."job_id" = $1 LIMIT 1  [["job_id", 13]]
  Rendered jobs/_job.html.erb (1.9ms)
  Order Load (0.3ms)  SELECT  "orders".* FROM "orders" WHERE "orders"."job_id" = $1 LIMIT 1  [["job_id", 34]]
  Rendered jobs/_job.html.erb (1.9ms)
  Order Load (0.4ms)  SELECT  "orders".* FROM "orders" WHERE "orders"."job_id" = $1 LIMIT 1  [["job_id", 64]]
  Rendered jobs/_job.html.erb (2.8ms)
  Order Load (0.4ms)  SELECT  "orders".* FROM "orders" WHERE "orders"."job_id" = $1 LIMIT 1  [["job_id", 94]]
  Rendered jobs/_job.html.erb (3.2ms)
  Order Load (0.4ms)  SELECT  "orders".* FROM "orders" WHERE "orders"."job_id" = $1 LIMIT 1  [["job_id", 60]]
  Rendered jobs/_job.html.erb (3.1ms)
  Order Load (0.4ms)  SELECT  "orders".* FROM "orders" WHERE "orders"."job_id" = $1 LIMIT 1  [["job_id", 29]]

尝试对相关数据使用预加载:

Job.joins('LEFT JOIN orders ON orders.job_id = jobs.id')
  .order("orders.featured")
  .preload(:orders)
Job.includes(:order).order("orders.featured")

Includes在视图中调用它之前不会将表连接在一起。它实际上将执行2个查询。如果您希望将这两个表连接起来以完成订单,则需要使用eager_load:

Job.eager_load(:order).order("orders.featured")

http://blog.bigbinary.com/2013/07/01/preload-vs-eager-load-vs-joins-vs-includes.html

最新更新