我目前有一個系統,用戶可以註冊和下注足球比賽的比分。 現在我有超過20K的用戶,並有超過300萬的投注。每週我必須生成一個排名,所以我必須加載在內存中的所有用戶用下注只是這樣的查詢:從實體框架中的LINQ查詢優化內存使用4.1
from u in context.Set<User>().include("Bets").OrderByDescending(u => u.Points)
select u
點在哪裏從每次猜測賺取積分的總和。 查詢結束後,我將用戶和他的位置保存在另一張桌子上,以建立我的排名。
問題是,這個查詢消耗的內存太多了!超過4GB!我需要所有用戶和投注來計算排名。
我嘗試的第一個選擇是:創建另一個表來存儲用戶及其點。我想在此查詢加載迭代,每次500個用戶,不是計算和保存,但我仍然停留在內存的問題:
int page = 0;
int step = 500;
while (page * step < count)
{
foreach (var u in context.Set<User>()
.Skip(page * step)
.Take(step).ToList())
{
//Saves in another table
}
page++;
}
//Sorts based on the data from this other table
因爲這沒有工作,我放棄了,然後我試圖做是這樣的:
var users = (from u in context.Set<User>().Include("Bets")
select u).ToList();
context.Dispose()
var sortedUsers = from u in users.OrderByDescending(u => u.Points)
select u;
但沒解決,以及...
我想這個問題是關於上下文保留所有跟蹤信息。 有沒有人有任何線索?如何使用EF 4.1處理大量數據?
感謝
,我注意到另一件事。 比方說,我有用戶A和用戶B, 每個人都有唯一1注相同的比賽,我希望有這樣的事情:
User A ---> Bet
\
Match
/
User B ---> Bet
但我有具有相同比賽的兩個不同的實例數據。 有沒有辦法避免這種情況?
爲什麼我不願意把這個在一個存儲過程:
排名是基於猜測,有關於這個排序的一些規則。
用戶有N個賭注。與有比分的比賽相關的每個投注。
第一個排序標準是要點。所以我需要計算每個賭注的分數(每個用戶有大約200個賭注,並且在冠軍結束時將有大約300個賭注)。這是第一次加入。
要計算每個投注的積分,我需要比賽的最終比分。這是另一個加入。
具有每個下注的點的總和(其具有約10條件語句),並通過將其分選後,我仍然需要基於來挑選:
正確投注號,投注其中的 號贏家被猜到了, 其中一個得分被猜測的投注, 最後一個投注日期, 註冊日期。
所以這是一個巨大的排序與約6準則,以及約3聯接和大量的邏輯。在LINQ中計算這個值是非常微不足道的,如果我不得不把它放在SP上,它會花費很多時間,並且更容易出錯。 (沒試過TDD,甚至單元測試的SP ...這個排名對一切測試)
如果您不需要更新這些'User'對象,我可以建議你使用存儲過程來做到這一點的計算。順便說一句,當你執行'.ToList()'時,你實現了你的查詢,並且實際上檢索你的數據庫中的所有數據到你的應用程序內存。 –
使用存儲過程是不現實的,計算比我在這裏發佈的要複雜得多。所以我正在計算內存。 –