• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

Ruby on rails开发从头来(五十九)- ActiveRecord基础(预加载子记录) ...

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

    预加载子记录讨论的问题和“延迟加载”是相同的。通常Active Record会推迟从数据库中加载子记录,直到你需要他们,例如,通过Rdoc中的例子,我们假定博客程序有一个Model,像下面这样:

class Post < ActiveRecord::Base

belongs_to :author

has_many :comments, :order => 'created_on DESC'

end

如果我们遍历所有的post,访问作者和评论属性,我们使用一个Sql查询来返回posts表中的多条记录,并且对于每条post记录都要执行一次Sql来访问authors表和comments表,总共是2n+1次。

for post in Post.find(:all)

puts "Post: #{post.title}"

puts "Written by: #{post.author.name}"

puts "Last comment on: #{post.comments.first.created_on}"

end

上面的代码存在着严重的性能问题,我们可以通过find方法的:include参数来修正它,在find方法被执行时,会列出需要延迟加载的关联。Active Record会很聪明地使用一条SQL一次加载数据,如果有100post,和上面的代码相比,下面的代码将会消除100次数据库查询:

for post in Post.find(:all, :include => :author)

puts "Post: #{post.title}"

puts "Written by: #{post.author.name}"

puts "Last comment on: #{post.comments.first.created_on}"

end

这个例子还可以更简化,只使用一条SQL

for post in Post.find(:all, :include => [:author, :comments])

puts "Post: #{post.title}"

puts "Written by: #{post.author.name}"

puts "Last comment on: #{post.comments.first.created_on}"

end

预加载子记录并不能保证改善性能(事实上,如果你的数据库不支持左连接,那么你就不能使用延迟加载,如果你使用的是oracle8,就必须要升级到oracle9才可以),因为预加载在Sql中加入了所有的表,这样就会有很多记录被加载后转换成Model类的对象,这样就有可能导致内存使用的问题,特别是当一条记录有很多条子记录时,这种情况就更明显,与一条条地延迟加载子记录相比,预加载会占用更多的服务器内存。

如果你使用了:include,你需要使用find方法的参数消除列名的歧义,在列名前添加表名来区分,在下面的例子中,title列需要添加表名前缀:

for post in Post.find(:all, :conditions => "posts.title like '%ruby%'",

:include => [:author, :comment])

# ...

end


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
ruby on rails + mysql 开发环境搭建发布时间:2022-07-14
下一篇:
ruby,sass安装发布时间:2022-07-14
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap