Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 我们为什么要避免1+;N查询问题?_Sql_Ruby On Rails_Ruby_Database - Fatal编程技术网

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}
如何比较呢*