我有兩個實體User和Place,並且它們之間具有多對多的關係,以便於用戶偏好某個地方的概念。有什麼解決方案可以避免Doctrine2中的聚合計數字段出現select(n + 1)問題?
作爲該功能的一部分,我希望Place實體包含一個字段,該字段可以爲我提供已收藏的用戶總數。我不需要用戶實體本身。
閱讀文檔,我找到了幾種解決方案,但我並不特別喜歡它們中的任何一種。
聚合字段
使用該溶液,我會簡單地爲收藏添加和刪除要更新的地點實體定義的整數字段。因此,該值不是即時計算的,而是作爲任何其他字段進行檢索。
我不喜歡這種方法,因爲存在併發性問題,並且使代碼中的管理變得不必要的複雜。
預先加載
使用這種方法,我會急切裝載的關係作爲一個雙向關聯,使得地方將加載已經收藏它作爲初始查詢過程的一部分的每個用戶實體。爲了計數,我只需要詢問其數量()。
這會導致查詢次數減少,但檢索的數據量太多,並且隨着時間的推移不能很好地擴展。
額外的延遲加載
這是我目前正在使用。它與Eager Loading解決方案類似,我確保這種關係是雙向的,只需向集合詢問其count(),但使用額外的懶惰獲取模式原則足夠智能,只需發出一個COUNT()查詢而不是檢索與Place實體關聯的整個用戶列表。
這裏的缺點是,如果我加載N Place實體,我需要N + 1個查詢,因爲每個Place將發出一個單獨的COUNT()查詢。
理想的解決方案
我的理想的解決辦法是找到一個方法來告訴學說執行第一查詢加載集合,然後第二個查詢加載集合中,然後爲ID的所有罪名在其各自的實體中填充字段。
我還沒有找到一種方法來做到這一點很容易。
有沒有人有任何這樣的例子,或者有其他解決方案來解決這個問題,我可能忽略?
編寫查詢不是問題,因爲爭論Doctrine理解如何處理數據。我希望它填充實體字段。如果可能的話,我希望避免特殊的標量查詢和數據傳輸。看來它可能不是,唉。 – 2014-08-29 16:18:42