class Mya < ActiveRecord::Base
has_many :mybs
end
class Myd < ActiveRecord::Base
belongs_to :myc
end
class Myc < ActiveRecord::Base
belongs_to :myb
has_many :myds
has_many :myes
end
class Myd < ActiveRecord::Base
belongs_to :myc
end
class Mye < ActiveRecord::Base
belongs_to :myc
end
比,我把一些测试数据插入MysqL :(种子)
mya=Mya.create!(title: 'first test')
i=0
10.times{
i=i+1
myb=Myb.create!(title: "my_#{i}")
5000.times{
myc=Myc.create!(mya_id: mya.id, myb_id: myb.id)
4.times {
myd=Myd.create!(mya_id: mya.id, myb_id: myb.id, myc_id: myc.id)
mye=Mye.create!(mya_id: mya.id, myb_id: myb.id, myc_id: myc.id)
}
}
}
在我的控制器中,我喜欢这样:
def index
@ms = Mya.first.to_json(:include => [{
mybs: {
:include => {
:mycs => {
:include => [:myds, :myes]
}
}
}
}
])
render json: @ms
end
它非常慢,帮助我,谢谢.抱歉我的英语.
github:https://github.com/scottxu/mytest
解决方法:
您正在运行双嵌套n 1查询.那意味着你
>查询所有(4)Myc的每个Myc(10 * 5000查询)
>查询每个Myc的所有(4)Myd(10 * 5000个查询)
这意味着您正在运行1 1 10(10 * 5,000)(10 * 5,000)= 100,012个查询.由于每个查询都需要从数据库发送和接收数据,因此每个查询都有一些开销,因此控制器操作变得非常慢.
您可以通过告诉ActiveRecord在第一个查询中使用includes
方法包含嵌套的Mybs Mycs和Myd来防止这种情况.这样,您只会执行一个大型查询,而ActiveRecord只会一次与数据库通信.
def index
@ms = Mya.includes(mybs: {mycs: [:myds, :myes]})
.first
.to_json(:include => [
# ...
])
render json: @ms
end
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。