我繼承了設計不佳的數據庫表(沒有主鍵或索引,超大的nvarchar
字段,日期存儲爲nvarchar
等)。這張表格大約有350,000條記錄。我按照預定義的時間間隔遞交了大約2000個潛在新記錄的列表,並且如果數據庫還沒有匹配的記錄,我必須插入任何可能的新記錄。在c中比較非常大的數據庫對象列表
我最初嘗試在foreach
循環中進行比較,但很快就很明顯,可能有更高效的方法。在做了一些研究之後,我嘗試了.Any()
,.Contains()
和.Exclude()
方法。
我的研究使我相信.Exclude()
方法將是最有效的方法,但在嘗試這種方法時會出現內存不足錯誤。 .Any()
和.Contains()
方法似乎都需要大致相同的時間來完成(這比foreach
循環更快)。
兩個列表的結構是相同的,每個包含多個字符串。如果你不介意的話,我有幾個問題沒有找到令人滿意的答案。
- 當比較兩個對象列表(由多個字符串組成)時,
.Exclude()
方法被認爲是最有效的方法嗎? 使用.Exclude()方法時有沒有使用投影的方法?我想找到一種方法來完成會是這樣的:
List<Data> storedData = db.Data; List<Data> incomingData = someDataPreviouslyParsed; // No Projection that runs out of memory var newData = incomingData.Exclude(storedData).ToList(); // PsudoCode that I would like to figure out if is possible // First use projection on db so as to not get a bunch of irrelevant data List<Data> storedData = db.Data.Select(x => new { x.field1, x.field2, x.field3 }); var newData = incomingData.Select(x => new { x.field1, x.field2, x.field3 }).Exclude(storedData).ToList();
使用SQL Server工作室經理原始的SQL語句,查詢超過10秒的時間會稍長。使用EF,似乎需要超過一分鐘。這是由EF差勁優化的SQL,還是EF的開銷造成了這種差異?
- 在這種情況下,EF中的原始SQL會是更好的做法嗎?
半題外話: 當從數據庫中抓取數據並將其存儲在變量storedData
,並能夠消除存儲在表中的任何索引的有用性(如果有任何)?
我不想問這麼多問題,而且我相信很多(如果不是全部的話)他們都不太好。但是,我無處可轉,我一直在尋找明確的答案。任何幫助非常讚賞。
UPDATE
經過進一步研究,我發現似乎是一個很好的解決了這個問題。使用EF,我從數據庫中獲取350,000條記錄,只保留創建唯一記錄所需的列。然後,我將這些數據轉換爲字典,將保留的列作爲關鍵字(如可以看到here)。這解決了返回的數據中已經存在重複的問題,並且使我能夠快速地將我新分析的數據與之進行比較。性能提升非常明顯!
我還不確定這是否會接近最佳實踐,但我當然可以接受這種表現。我也看到了一些對ToLookup()
的引用,我可能會嘗試着去看看那裏是否有性能上的提升。不過,這裏是一些代碼來顯示我所做的:
var storedDataDictionary = storedData.GroupBy(k => (k.Field1 + k.Field2 + k.Field3 + k.Field4)).ToDictionary(g => g.Key, g => g.First());
foreach (var item in parsedData)
{
if (storedDataDictionary.ContainsKey(item.Field1 + item.Field2 + item.Field3 + item.Field4))
{
// duplicateData is a previously defined list
duplicateData.Add(item);
}
else
{
// newData is a previously defined list
newData.Add(item);
}
}
'350,000條記錄'似乎並不大。把所有的數據都存入內存,並用linq2objects完成你的工作....(當然,如果它只是一次性工作) – Eser
我實際上已經使用上述幾種方法正確地運行了查詢。我更期待什麼可以被認爲是最有效的或最佳的做法。 – FlipperBizkut
這取決於你的技能......我會用SQL做這樣的工作。 RDBMS完美地用於處理數據。如果允許改變結構,我會在一個好的桌子設計上投入一些思考,並首先將醜陋的數據轉移到新的結構中。如果你必須堅持這種結構,那麼RDBMS更適合處理大於RAM的數據。 – Shnugo