2014-01-10 58 views
1

假設我的SQL數據庫中有兩個表。 1,一箇中等大小的表與成千上萬的記錄叫MYTABLE1 2.大桌數百萬條記錄(和與日俱增)稱爲MyTable2使用LINQ to Entities多次枚舉大型數據集

MYTABLE1和MyTable2都有一個叫做哈希屬性,可以相等。

我正在尋找使用Linq to Entities迭代MyTable1並查找MyTable2中具有相同散列並保存到另一個表中的所有記錄的最有效方法。以下是代碼外觀的簡化視圖。

using(var db = new context()) { 
    var myTable1Records = db.MyTable1.Select(x => x); 

    foreach(var record in myTable1Records) { 
     var matches = db.MyTable2.Where(y => y.Hash.Equals(record.Hash)).Select(y => y); 
     foreach(var match in matches) { 
      // Add match to another table 
     } 
    } 
} 

我看到這個代碼的性能顯着減慢,因爲MyTable2的大小每天都在變大。我正在嘗試用於有效處理這種情況的一些想法是:

  1. 在db.MyTable2上設置MergeOption.NoTracking,因爲它純粹是讀取操作。遺憾的是,還沒有看到很多改進。
  2. 使用.ToList()將MyTable2拉入內存中以消除對db的多次調用創建MyTable2的「代碼塊」,以便代碼可以遍歷,因此每次都不會查詢全部百萬條記錄。

我很想看看有沒有其他技術或魔法彈可以在這種情況下有效。謝謝!

+3

檢查? – MoZahid

+0

您是否必須爲c#帶來數百萬個值才能完成RDMS可以非常有效地完成的任務? –

+1

這可能有點偏離使用Linq的主題,但是如何在這兩個基於'Hash'字段連接的表中創建一個視圖,然後查詢連接的表? - 讓你的數據庫在這部分爲你做好工作......這就是它被優化的原因! –

回答

1

你有一個屬性叫Hash。用它作爲散列!將第一個表格存儲在Dictionary中,並以Hash爲關鍵字,然後遍歷第二個表格,檢查Dictionary中的匹配項,再次鍵入Hash

或者,更好的是,使用LINQ:

var matches = db.MyTable1.Intersect(db.MyTable2); 

如果你需要做一個自定義比較,創建一個IEqualityComparer。 (我假設你正在做某種類型的投影,並且Select(x => x)是用於此問題目的的佔位符。)

或者更好的是,此操作可能會更好地完全在數據庫中進行存儲程序或視圖。你基本上正在做一個JOIN,但使用C#來做到這一點。從數據庫到客戶端應用程序的往返時間花費在數據庫服務器上可能會做的所有事情上。

1

你在這裏做的是執行一個內部連接。通過使用查詢提供程序,您甚至可以確保這項工作在數據庫一側完成,而不是在應用程序的內存中完成;你只會拉下匹配的結果,不再:

var query = from first in db.MyTable1 
    join second in db.MyTable2 
    on first.Hash equals second.Hash 
    select second; 
1

可能索引你的哈希列可以提供幫助。假設散列是char或varchar類型,索引可以支持的最大長度是900個字節。

CREATE NONCLUSTERED INDEX IX_MyTable2_Hash ON dbo.MyTable2(Hash); 

索引編VARCHAR的表現,你可能希望你有在分貝上的哈希colums索引來這裏 SQL indexing on varchar