Sql 我们为什么要避免1+;N查询问题?
听起来可能有点傻,但我不是数据库专家 例如,如果我们有一个Sql 我们为什么要避免1+;N查询问题?,sql,ruby-on-rails,ruby,database,Sql,Ruby On Rails,Ruby,Database,听起来可能有点傻,但我不是数据库专家 例如,如果我们有一个用户模型和一个注释模型,并且每个注释都属于一个用户,那么有两种方法可以获取所有注释及其用户: # 1. @comments = Comment.all(:include => :user) # 2. @comments = Comment.all() @users = [] @comments.each do |comment| # Or we do the same loop in embedded code in the v
用户
模型和一个注释
模型,并且每个注释都属于一个用户,那么有两种方法可以获取所有注释及其用户:
# 1.
@comments = Comment.all(:include => :user)
# 2.
@comments = Comment.all()
@users = []
@comments.each do |comment| # Or we do the same loop in embedded code in the view
@users << User.find(comment.user)
end
#1。
@comments=Comment.all(:include=>:user)
# 2.
@comments=Comment.all()
@用户=[]
@comments.each do | comment |#或我们在视图中的嵌入式代码中执行相同的循环
@用户反复点击数据库以获取与注释
记录关联的用户
记录将影响应用程序的性能
如果评论的数量太多,并且您正在循环浏览它以获取所有相关用户,那么这将变得更加缓慢
而在Comment.all(:include=>:user
的情况下,始终只会触发两个查询。一个用于获取注释,另一个用于获取所有关联用户。反复点击数据库以获取与Comment
记录关联的用户
记录将影响应用程序的性能
如果评论的数量太多,并且您正在循环浏览它以获取所有相关用户,那么这将变得更加缓慢
然而,如果是Comment.all(:include=>:user
),则始终只会触发两个查询。一个用于获取评论,另一个用于获取所有关联用户。请允许我说明原因:
Message.count
13228
Benchmark.measure { Message.all.each(&:user) }
16s
Benchmark.measure { Message.all(include: :user).each(&:user) }
2s
有100行,这是一个更现实的获取:
Benchmark.measure { Message.limit(100).each(&:user) }
0.12s
Benchmark.measure { Message.includes(:user).limit(100).each(&:user) }
0.01s
如您所见,数据库的速度快了约10倍,压力也小了。请允许我说明原因:
Message.count
13228
Benchmark.measure { Message.all.each(&:user) }
16s
Benchmark.measure { Message.all(include: :user).each(&:user) }
2s
有100行,这是一个更现实的获取:
Benchmark.measure { Message.limit(100).each(&:user) }
0.12s
Benchmark.measure { Message.includes(:user).limit(100).each(&:user) }
0.01s
正如您所看到的,大约快10倍,对数据库的压力也更小。因为更多的查询通常意味着更差的性能,而执行100个可以减少到2个的查询是毫无意义的。@DamienRoche一个查询需要什么样的开销才能使更多的查询更差的性能?我将在回答中演示。。这也在中进行了解释ActiveRecord查询接口的“13个急切加载关联”,请参阅,因为更多的查询通常意味着更差的性能,执行100个可减少到2个的查询是毫无意义的。@DamienRoche一个查询需要什么样的开销才能使更多的查询更差的性能?我将在回答中演示。。这也在在ActiveRecord查询界面的“13个即时加载关联”中,请参见如何Message.all.map!{| Message | Message | Message.user}
compare?@Drew恐怕这是无效的语法。你能重新检查一下吗?无论哪种方式,调用消息。不包含的用户
仍将导致13k查询,而不是2个。哈哈,是的,我想不起来合并两个数组的命令是什么,但无论如何,我不知道为什么我认为这样会更快!haha@Drew哈哈!我实际上,你想说的是{message | message | | | | message.user}
,这当然只会获取消息。如何message.all.map!{message | message | message |=message.user}
比较?*如何message all.map!{message message | message | message.user}
compare?@Drew恐怕这是无效的语法。你能重新检查一下吗?无论哪种方式,调用消息。不包含的用户
仍将导致13k查询,而不是2个。哈哈,是的,我想不起来合并两个数组的命令是什么,但无论如何,我不知道为什么我认为这样会更快!haha@Drew哈哈!我实际上,你想说的是{message | message | | | | message.user}
这当然只会获取消息。那么message.all.map!{message | message |=message.user}
如何比较呢*