Rails 浅谈 ActiveRecord 的 N + 1 查询问题

问题原因:在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 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章