2011-06-15 57 views
0

我有兩種模式UserBrand,以及它們之間的多對多關係(通過UserBrand表)。我有大約一千個用戶,一千個品牌和一百個最喜歡的品牌。優化計算建議並與多對多關係工作

User.all.count # => 1000 
Brand.all.count # => 1000 
User.find(1).brands # => 100 

如果我想找到5個用戶,其中最喜歡的品牌幾乎等於當前用戶,我寫在用戶模式

class User < ActiveRecord::Base 
    has_many :user_brands 
    has_many :brands, :through => :user_brands 

    def similar_users 
    result = {} 

    User.all.each do |u| 
     result[u] = shared_brands_with u.brands 
    end 

    result.sort{ |a, b| b[1] <=> a[1] }[1..5].map!{ |e| e[0] } 
    end 

    def shared_brands_with(brands) 
    (brands & @brands).size 
    end 
end 

以下,並在users/show視圖

以下
<h2>Similar users</h2> 
<ul> 
    <% @user.similar_users.each do |user| %> 
    <li><%= link_to user.name, user %></li> 
    <% end %> 
</ul> 

但在瀏覽器中查看用戶建議大約需要30-60秒。

所以我的問題是「我如何加快計算建議?」

UPD:使用

User.includes(:brands).each do |u| 
     result[u] = shared_brands_with u.brands 
    end 

性能加倍,但即使有50個品牌,而不是100,在10秒內給的建議是非常緩慢的。

回答

0

所以,基本上。您正在拉動整個用戶表。對於每一個,抓住該用戶的品牌名單,大概是品牌本身。並過濾。我不會認爲它速度很快。 :-)

您將需要在SQL中重寫該邏輯以使其更快。對不起,我不比紅寶石更流利 - 無法真正理解標準......但實際上,通過一個查詢獲取品牌。

它會很大很醜,充滿了連接和in(),可能還有group by/having子句,但它會比現在的方法更快。

+0

你可以幫助那些SQL的?我不熟悉SQL查詢。 有三個表格: **用戶**帶字段__id__,__name__; **品牌**與__id__和__name__; ** UserBrand ** with __id__,__user_id__ and __brand_id__ – 2011-06-15 18:27:59