我试图在ActiveRecord查询中解决N + 1问题。我想知道为什么order
会产生N + 1问题。如果我删除它,它运作良好。看看这个:
效果正常
Rental.eager_load(:customer).limit(5).first.customer
SQL (1.7ms) SELECT "rentals"."id" AS t0_r0, "rentals"."customer_id" AS t0_r1, "rentals"."movie_id" AS t0_r2, "rentals"."created_at" AS t0_r3, "rentals"."updated_at" AS t0_r4, "customers"."id" AS t1_r0, "customers"."firstname" AS t1_r1, "customers"."lastname" AS t1_r2, "customers"."email" AS t1_r3, "customers"."stripe_id" AS t1_r4, "customers"."country" AS t1_r5, "customers"."city" AS t1_r6, "customers"."street_address" AS t1_r7, "customers"."zip_code" AS t1_r8, "customers"."state" AS t1_r9, "customers"."created_at" AS t1_r10, "customers"."updated_at" AS t1_r11, "customers"."encrypted_password" AS t1_r12, "customers"."reset_password_token" AS t1_r13, "customers"."reset_password_sent_at" AS t1_r14, "customers"."remember_created_at" AS t1_r15, "customers"."sign_in_count" AS t1_r16, "customers"."current_sign_in_at" AS t1_r17, "customers"."last_sign_in_at" AS t1_r18, "customers"."current_sign_in_ip" AS t1_r19, "customers"."last_sign_in_ip" AS t1_r20, "customers"."gender" AS t1_r21 FROM "rentals" LEFT OUTER JOIN "customers" ON "customers"."id" = "rentals"."customer_id" LIMIT 5
=> [#<Rental id: 7884, customer_id: 10001, movie_id: 756, created_at: "2013-10-16 08:45:50", updated_at: "2013-10-16 08:45:50">, #<Rental id: 8529, customer_id: 10001, movie_id: 870, created_at: "2014-03-24 05:22:13", updated_at: "2014-03-24 05:22:13">, #<Rental id: 12926, customer_id: 10001, movie_id: 805, created_at: "2014-11-26 07:00:47", updated_at: "2014-11-26 07:00:47">, #<Rental id: 7841, customer_id: 10002, movie_id: 480, created_at: "2016-01-15 02:55:03", updated_at: "2016-01-15 02:55:03">, #<Rental id: 13824, customer_id: 10002, movie_id: 537, created_at: "2013-08-12 12:46:25", updated_at: "2013-08-12 12:46:25">]
产生N + 1问题
现在,我只是在查询中添加.order(created_at: :desc)
。
Rental.eager_load(:customer).order(created_at: :desc).limit(5).each {|x| x.customer}
SQL (37.4ms) SELECT "rentals"."id" AS t0_r0, "rentals"."customer_id" AS t0_r1, "rentals"."movie_id" AS t0_r2, "rentals"."created_at" AS t0_r3, "rentals"."updated_at" AS t0_r4, "customers"."id" AS t1_r0, "customers"."firstname" AS t1_r1, "customers"."lastname" AS t1_r2, "customers"."email" AS t1_r3, "customers"."stripe_id" AS t1_r4, "customers"."country" AS t1_r5, "customers"."city" AS t1_r6, "customers"."street_address" AS t1_r7, "customers"."zip_code" AS t1_r8, "customers"."state" AS t1_r9, "customers"."created_at" AS t1_r10, "customers"."updated_at" AS t1_r11, "customers"."encrypted_password" AS t1_r12, "customers"."reset_password_token" AS t1_r13, "customers"."reset_password_sent_at" AS t1_r14, "customers"."remember_created_at" AS t1_r15, "customers"."sign_in_count" AS t1_r16, "customers"."current_sign_in_at" AS t1_r17, "customers"."last_sign_in_at" AS t1_r18, "customers"."current_sign_in_ip" AS t1_r19, "customers"."last_sign_in_ip" AS t1_r20, "customers"."gender" AS t1_r21 FROM "rentals" LEFT OUTER JOIN "customers" ON "customers"."id" = "rentals"."customer_id" ORDER BY "rentals"."created_at" DESC LIMIT 5
Customer Load (0.9ms) SELECT "customers".* FROM "customers" WHERE "customers"."id" = $1 LIMIT 1 [["id", 20288]]
Customer Load (0.7ms) SELECT "customers".* FROM "customers" WHERE "customers"."id" = $1 LIMIT 1 [["id", 20288]]
Customer Load (0.7ms) SELECT "customers".* FROM "customers" WHERE "customers"."id" = $1 LIMIT 1 [["id", 20274]]
Customer Load (0.7ms) SELECT "customers".* FROM "customers" WHERE "customers"."id" = $1 LIMIT 1 [["id", 20284]]
=> [#<Rental id: 38836, customer_id: 20288, movie_id: 681, created_at: "2016-10-17 23:48:00", updated_at: "2016-10-17 23:48:00">, #<Rental id: 38833, customer_id: 20288, movie_id: 782, created_at: "2016-10-17 23:35:00", updated_at: "2016-10-17 23:35:00">, #<Rental id: 38767, customer_id: 20274, movie_id: 563, created_at: "2016-10-17 23:17:00", updated_at: "2016-10-17 23:17:00">, #<Rental id: 38664, customer_id: 20254, movie_id: 594, created_at: "2016-10-17 23:15:00", updated_at: "2016-10-17 23:15:00">, #<Rental id: 38815, customer_id: 20284, movie_id: 659, created_at: "2016-10-17 23:05:00", updated_at: "2016-10-17 23:05:00">]
我错过了什么吗?如何解决N + 1查询?
更新:
:asc
而不是:desc
排序,那么就没有N + 1问题。:id
上:asc
的{{1}}等其他字段进行排序,那么就没有N + 1问题。