程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Ruby on rails開發從頭來(五十九)- ActiveRecord基礎(預加載子記錄)

Ruby on rails開發從頭來(五十九)- ActiveRecord基礎(預加載子記錄)

編輯:關於JAVA

預加載子記錄討論的問題和“延遲加載”是相同的。通常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一次加載數據,如果有100個post,和上面的代碼相比,下面的代碼將會消除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
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved