听起来有点愚蠢,但我不是数据库专家。
例如,如果我们有User
模型和Comment
模型,并且每条评论都属于某个用户,则有两种方法可以获取所有评论及其用户:
# 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
我的问题是,由于这两种方法都会获取所有评论及其用户数据(这意味着我们从硬盘驱动器和互联网上读取和传输相同数量的信息),为什么第二种方法被视为不良做法?
答案 0 :(得分:4)
请允许我说明原因:
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倍,压力也减轻了。
答案 1 :(得分:2)
一次又一次地访问数据库以获取与User
记录关联的Comment
记录将影响您的应用程序的性能。
如果评论数量太高而你正在循环播放它以获得所有相关用户,那就变得更加缓慢。
在Comment.all(:include => :user
的情况下,只会一次触发两个查询。一个获得评论,一个获得所有相关用户。