rails: N+1 查询问题以及优化
N+1 查询问题,以及优化方案
问题
N+1 查询问题是指在获取关联数据时,产生大量额外数据库查询的性能问题。
# 获取所有文章
posts = Post.all
# 遍历文章并访问关联的用户信息
posts.each do |post|
puts post.user.name # 每次都会查询数据库!
endps: 测试数据
posts = Post.limit(10) # 只取10篇,避免输出太多
posts.each { |post| puts post.user.name }
查询次数分析
执行的查询:
1 次查询获取所有文章:SELECT * FROM posts
N 次查询获取每个文章的用户:SELECT * FROM users WHERE id = ? (N = 文章数量)
如果数据库中有 100 篇文章,就会执行 1 + 100 = 101 次查询!使用预加载(eager loading)
# 预加载关联数据
posts = Post.includes(:user)
posts.each do |post|
puts post.user.name # 不会再次查询数据库
end查询分析
1 次查询获取文章:SELECT * FROM posts
1 次查询获取所有相关用户:SELECT * FROM users WHERE id IN [1,2,3,4,5...]
总共只执行 2 次查询,而不是 1+N 次!ps: 测试数据
posts = Post.includes(:user).limit(10)
posts.each { |post| puts post.user.name }