问题原因:在Rails中使用ActiveRecord时,常会嵌套遍历model查询数据,或者一次查询某个表的所有数据,此时查看日志或在交互终端测试代码发现,sql语句是执行多次(N+1次)的,如下执行结果:
Post.all.map{|post| post.comments}
Post Load (0.3ms) SELECT "posts".* FROM "posts"
Comment Load (0.2ms) SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = ? [["post_id", 1]]
Comment Load (0.4ms) SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = ? [["post_id", 2]]
Comment Load (0.6ms) SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = ? [["post_id", 3]]
Comment Load (0.6ms) SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = ? [["post_id", 4]]
解决方案:includes预加载
Post.includes(:comments).map{|post| post.comments}
Post Load (0.2ms) SELECT "posts".* FROM "posts"
Comment Load (0.5ms) SELECT "comments".* FROM "comments" WHERE "comments"."post_id" IN (1, 2, 3, 4)
案例说明:
class Dormitory < ActiveRecord::Base
has_many :stus, class_name: StuDormitory, foreign_key: :dormitory_code
end
class StuDormitory < ActiveRecord::Base
belongs_to :dormitory, class_name: Dormitory, foreign_key: :dormitory_code
end
查询某个宿舍所有的学生信息:
Dormitory.where(dormitory_code: "001").includes(:stus)
参考资料:
https://ruby-china.org/topics/32364
https://ruby-china.org/topics/17866
https://ruby-china.github.io/rails-guides/association_basics.html#the-belongs-to-association