問題原因:在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