3
在我的rails項目中,我有一項功能可以顯示用戶是否有任何Facebook好友已經在該網站上。驗證後,我打開他們的Facebook朋友到@fb_friends然後做到這一點:Rails Active Record:如何減少訪問數據庫的次數?
@fb_friends.each do |friend|
friend_find = Authorization.find_by_uid_and_provider(friend[:identifier], 'facebook')
if friend_find
@fb_friends_on_cody << friend_find.user_id
@fb_friends.delete(friend)
end
end
基本上,如果發現匹配(通過授權表),我推說記錄@fb_friends_on_cody。這被證明是一個非常昂貴的操作:
這個命中每個朋友一次數據庫。所以在我的情況下,總共執行了582個查詢。
每個Authorization.find_by_uid_and_provider的性能都很差。我有添加索引,像這樣:
我想了很多的性能增益可以通過解決第一點可以看出。也許有一些方法可以使查詢本身更高效。欣賞這些方面的任何提示。
解決方案
使用Unixmonkey的指導下,我能夠查詢的數量減少,從582到1!下面是最終代碼:
friend_ids = @fb_friends.map{|f| f[:identifier] }
authorizations = Authorization.where('provider = ? AND uid IN (?)','facebook',friend_ids)
@fb_friends_on_cody = authorizations.map{ |a| { user_id: a.user_id, uid: a.uid }}
@fb_friends.reject!{|f| @fb_friends_on_cody.map{|f| f[:uid]}.include?(f[:identifier]) }
啊。你打敗了我。 OP:http://www.w3schools.com/sql/sql_in.asp – joslinm 2012-07-26 20:45:06
謝謝!它不喜歡這行'@ fb_friends.delete_all('(')',@fb_friends_on_cody)''可能是因爲@fb_friends是一個數組(不是ActiveRecord)。我需要爲數組找到一個類似的「delete_all」方法。 – pejmanjohn 2012-07-26 20:50:41
'@ fb_friends.reject!{| f | @ fb_friends_on_cody.include?(f.id)}' – Unixmonkey 2012-07-26 20:53:08