2011-06-18 36 views
1

我正在使用Ruby on Rails 3.0.7,並試圖最小化數據庫擊中。爲此,我從數據庫中檢索與User相關的所有對象Article,然後對這些檢索到的對象執行搜索。性能:儘量減少數據庫擊中

我要做的就是:

stored_objects = Article.where(:user_id => <id>) # => ActiveRecord::Relation 

<some_iterative_function_1>.each { |...| 
    stored_object = stored_objects.where(:status => 'published').limit(1) 
    ... 
    # perform operation on the current 'stored_object' considered 
}  
<some_iterative_function_2>.each { |...| 
    stored_object = stored_objects.where(:visibility => 'public').limit(1) 
    ... 
    # perform operation on the current 'stored_object' considered 
} 
<some_iterative_function_n>.each { |...| 
    ... 
} 

stored_object = stored_objects.where(:status => 'published')代碼真的會避免進入數據庫(我問這個,因爲在我的日誌文件時,它仍然接縫運行each迭代數據庫查詢)?如果不是,我怎樣才能最小化數據庫擊中?

P.S .:用幾句話,我想要做的是在ActiveRecord::Relation(一個數組)上工作,但調用它的where方法接近數據庫。

+0

如果你真的在做* *搜索,就像你提到的那樣,你應該使用像Solr這樣的搜索特定的解決方案。與RDBMS或應用內解決方案相比,他們在處理此問題方面要好得多。 – coreyward

+0

我不知道是否有這種情況,但要小心過早的優化,從我的atciverecord的經驗來看,通常只要你有適當的索引,你通常會把大部分時間用在ruby代碼中,而不是數據庫中。 – Schmurfy

+0

@Schmurfy - 你能更清楚嗎? – user502052

回答

1

Rails具有一次抓取數據庫塊的功能,然後遍歷行而不必再次訪問數據庫。

有關find_eachfind_in_batches的更多信息,請參閱「Retrieving Multiple Objects in Batches」。

1

一旦你開始迭代stored_objects(如果這就是你正在做的),它們將從數據庫加載。如果你想只加載用戶的發表的文章,你可以這樣做:

stored_objects = Article.where(:user_id => id, :status => 'published') 

如果你不是要讀取出版未發表的文章,做一些與發佈者不同,你可以這樣做:

stored_objects = Article.where(:user_id => id) 
stored_objects.find_all { |a| a.status == 'published' }. each do |a| 
    # ... do something with a published article 
end 

或許:

Article.where(:user_id => id).each do |article| 
    case article.status 
    when 'published' 
     # ... do something with a published article 
    else 
     # ... do something with an article that's not published 
    end 
end 

每個例子只執行一個數據庫查詢。選擇哪一個取決於您真正想要處理的數據。

+0

也許你應該增加一些限制,否則你會打內存。 –

+0

我需要單獨考慮每個'stored_object'以便在其他操作上運行。此外,我需要基於其他屬性值來查找'條款'對象......這就是爲什麼我想要檢索與用戶有關的所有文章,然後每次處理那些沒有訪問數據庫的文章。 – user502052

+0

也許我誤解了這個問題。你可以無限期地連接Relation的'where'方法,而不會觸及數據庫,但是當你試圖檢查一個結果時,就需要去得到一個結果。 –