2016-02-03 36 views
1

我遇到以下問題。我需要對名爲專業人士的表進行大量查詢,但我需要優化查詢,因爲對於每位專業人員,我都會調用關聯的表。包含在Rails中的查詢

但我有兩個相關表的問題:評論和關稅。

評論:

我要打電話去各專業的3條評論。我試着用:

@professionals.includes(:comments).where(:comments => { type: 0 }).last(3) 

查詢只帶來了3名專業人士,這個問題不是我所需要的,都只有三個意見,其中類型等於零的專業人士。

,當我嘗試:

@professionals.includes(:comments).where(:comments => { type: 0 }) 

結果是隻(所有的)意見的專業人士,當我需要的所有專業的有或無意見。但是,如果專業有意見,我只需要在最後的三點意見,其中類型是等於零

關稅:

關稅問題我有一個類似的問題,在這種情況下,我需要的最後4運價爲每專業的。我嘗試:

@professionals.includes(:tariffs).last(4) 

但只帶來了最後4名專業人士。

型號:

class Comment < ActiveRecord::Base 
     belongs_to :client 
     belongs_to :professional 

end 

class Professionals < ActiveRecord::Base 
     has_many :comment 

end 
+0

我真的不明白你的第二個選擇的問題。你爲所有專業人士提供所有相關評論,這很好。如果您想要爲專業人士提供最後3個職位,則可以在查詢中循環訪問專業人員時調用professional.comments.limit(3)或professional.last(3)。第一個會返回一個ActiveRecord :: Relation,第一個會返回一個Array。你能否顯示你想使用每位專業人士的最後3條評論? –

+0

您需要在WHERE子句中運行子查詢來計算註釋的數量。然而,如何做到這一點(更重要的是如何在不殺死性能的情況下做到這一點)取決於您使用的RBDMS。 '.last(3)'不起作用,因爲它將「LIMIT」應用於整個查詢。 – max

回答

2

你不能在接頭表中ActiveRecord使用限制。 limit適用於第一個關係,在這種情況下碰巧是@professionals

您有幾種選擇選擇:

  1. 預加載的所有意見,各專業和限制他們的輸出(減少了所需查詢的數量,但會增加內存消耗,因爲你可能預載了很多AR對象) 。
  2. 延遲加載所需的註釋數量(增加了n + 1的查詢數量,但減少了潛在的內存消耗)。
  3. 使用原始SQL編寫自定義查詢。

如果預先加載所有內容,則不需要太多改變。只需限制通過每個@professional的白色迭代的評論數量即可。

@professionals.each do |professional| 
    @professional.comments.limit(3) 
end 

如果你懶負荷只有你所需要的,那麼你會在limit範圍適用於評論的關係。

@professionals.all 
@professionals.each do |professional| 
    @professional.comments.where(type: 0).limit(3) 
end 

編寫自定義查詢有點複雜。但是你可能會發現它的性能可能會降低,具體取決於你必須建立的連接數量以及你的表格的索引性能。

我建議你採取方法二,並使用查詢和片段緩存來提高性能。例如:

- cache @professionals do 
    - @professionals.each do |professional| 
    - cache professional do 
     = professional.name 

這種方法將訪問數據庫的第一次,但後續加載後評論將從緩存中讀取,避免了DB命中。您可以在Rails Guides中閱讀有關緩存的更多信息。

+0

謝謝,這工作 –