2011-04-27 36 views
5

這屬於我正在繼承的項目,不能更改表結構或數據訪問模型。我被要求優化用於將數據插入數據庫的算法。用於合併數據的實體框架算法

我們在表T從這個數據集,我們拉了一套我們稱之爲答:我們也查詢XML提要並獲得了一套我們稱之爲X.

  • 如果從X的值在A中,記錄在A中必須更新以反映X.record的數據
  • 如果X中的值不在A中,則X.record必須插入到A中
  • 如果來自A的值不在X中A.record必須保存在A中
  • X必須完全遍歷所有記錄,並且A必須更新

所有這些更改都需要插回到數據庫中。

AS的算法中執行以下操作:

Query XML into a LIST 
foreach over the XML LIST 
    look up foreach.item in A via LINQ (i.e. query = from record in A where 
                 record.GUID == foreach.item.GUID 
                 select record) 
    if query.Count() == 0 
     insert into A (via context.AddToTableName(newTableNameObject) 
    else 
     var currentRecord = query.First() 
     set all properties on currentRecord = properties from foreach.item 
     context.SaveChanges() 

我知道這是次優的。我試圖將A轉換成foreach循環之外的一個對象(稱爲queryA),以便將查詢移動到內存中而不是擊中磁盤,但是在思考完後,我意識到數據庫已經在內存中。

在計算器中添加了定時器對象後,很明顯最耗時的是SaveChanges()函數調用。在某些情況下,它是20ms,而在另一些情況下,可以明確地說,它會跳到100ms。

我寧願只調用一次SaveChanges()。鑑於我對EF的深入瞭解(最好是薄的)以及無法更改表格結構以及必須保留A中不包含X的數據的限制,我無法弄清楚該怎麼做。

對此提出建議?

+0

您提到您無法更改數據訪問模型。所以無法批量插入扁平化的XML並在目標數據庫中運行MERGE? – 2011-05-09 23:16:59

回答

4

我不認爲你會使用實體框架時提高性能:

查詢

  • 通過加載單獨的查詢每個記錄並不好
  • 可以提高通過在同一查詢中加載多個記錄來提高性能。例如,您可以使用||加載小批記錄在條件或Contains(如SQL中的IN)。 Contains僅受.NET 4.0支持。
  • 另一個改進可以是用存儲過程替換查詢,並使用X.Guids將所有guid傳遞給SQL Server連接A並獲得結果。表值參數僅在SQL 2008及更新版本上受支持。

數據修改

  • 不必 每次修改後應該不叫SaveChanges。你可以在foreach循環之後調用它,它仍然可以工作。它將通過單筆交易 的所有修改,但您不會通過此類操作 this answer獲得任何性能提升,它可以給您帶來顯着提升。
  • EF doesn't support command batching因爲每個更新或插入總是單獨往返數據庫。除了實施全新的EF ADO.NET提供程序(就像開始一個新項目),使用EF修改數據時沒有辦法解決這個問題。
  • 再次溶液是通過使用具有表值參數存儲過程減少往返
  • 如果DB還使用GUID作爲主鍵和聚集索引你通過reordering index after each insert有另一個性能降低=在磁盤上修改數據。

問題不在算法中,而在於處理用於處理數據的數據和技術的方式。實體框架不適合數據泵使用。你應該將這些信息交給你的老闆,因爲提高性能意味着你的應用程序的更復雜的變化。這不是你的錯,它不是程序員做這個應用程序的錯。這是EF的一個特徵,它不是很知名,因爲我知道它在任何MS最佳實踐中都沒有明確說明。

+1

「,但不會因此類操作而獲得任何性能提升。」:當我在每條記錄之後不調用SaveChanges()時,我對插入質量的性能有了極大的提升。你有沒有看到我的測量在這裏:http://stackoverflow.com/questions/5940225/fastest-way-of-inserting-in-entity-framework/5942176#5942176也許我做錯了什麼或更新它是另一個故事比插入。 – Slauma 2011-05-09 22:20:00

+0

@Slauma:我相信你的實驗,也許我會在晚些時候嘗試。我修改了我的答案。 – 2011-05-09 22:47:31

+0

看看我對這個answare的評論http://stackoverflow.com/questions/5940225/fastest-way-of-inserting-in-entity-framework/5942176#5942176每次插入FOR ME後SavinChanges在做開銷,實現溶液提供的解決方案顯着降低插入時間 – 2011-05-10 16:26:38