按孩子的属性排序时n + 1问题

时间:2015-05-15 17:08:03

标签: ruby-on-rails activerecord

以下查询遇到加载每条记录的每个订单的“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]]

2 个答案:

答案 0 :(得分:0)

尝试将preload用于关联数据:

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

答案 1 :(得分:0)

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

包括不将表连接在一起,直到您在视图中调用它为止。它实际上会做2个查询。如果您希望连接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