2011-09-21 102 views
4

好的,我有一堆我需要迭代的複雜邏輯。我正在調用Web服務並獲取結果。我將結果通過它們循環並根據各種規則進行不同的數據庫調用。Linq to SQL循環性能

我用最初的代碼爲以下幾點:

foreach(var obj in MyObjects) 
{ 
    using(var connection = new LinqToSqlDBContext()) 
    { 
     connection.StoredProc1(obj.Name); 
     connection.StoredProc2(obj.Name); 
     connection.SubmitChanges(); 
    } 
} 

我想這將是更有效的:

using(var connection = new LinqToSqlDBContext()) 
{ 
    foreach(var obj in MyObjects) 
    { 
     connection.StoredProc1(obj.Name); 
     connection.StoredProc2(obj.Name);  
    } 
    connection.SubmitChanges(); 
} 

是否有更好的方法可以讓我這樣做是爲了提高性能?我正在使用Linq to SQL類和C#4.0。

謝謝!

回答

4

由於您正在調用stored-procs,但未執行對象更改,因此SubmitChanges()是多餘的。在正常使用情況下,我期望這個SubmitChanges是一個重要的因素,所以平衡調用數量與單個事務的大小是很重要的。然而,在這裏並不適用,所以我只想用:

using(var connection = new LinqToSqlDBContext()) 
{ 
    foreach(var obj in MyObjects) 
    { 
     connection.StoredProc1(obj.Name); 
     connection.StoredProc2(obj.Name);  
    } 
} 
2

是的,我認爲2一個更好,因爲你正在更新數據只是建立連接,因爲在1你正在丟棄和再次連接,以便它增加了丟棄和獲得與數據庫連接的成本。

+1

由於連接池(sql-server默認啓用),開銷很小, –

2

考慮分批通過使程序的存儲過程中執行的操作接受的名稱,而不是一個名稱的列表。這可以使用Table-Valued參數來實現。

2

與以往一樣 - 這取決於

在您的示例中,第一個代碼塊運行存儲過程並在單獨的事務中爲每個對象提交更改。

然而,第二個代碼塊執行存儲過程,然後在一次事務中一次提交所有更改。

這可能會更高效,這取決於您的應用程序。

最重要的是,如果可以的話,就是減少數據庫調用次數。因此,如果您可以重寫存儲過程以獲取名稱列表而不是單個名稱,然後在數據庫服務器上執行循環,則很可能會看到性能顯着提高。

注意,有在打開和關閉連接相關做法通常小的開銷,因爲它們是在連接池通常緩存。所以,

using(var connection = new LinqToSqlDBContext()) 
{ 
    foreach(var obj in MyObjects) 
    { 
     connection.StoredProc1(obj.Name); 
     connection.StoredProc2(obj.Name);  
    } 
} 

foreach(var obj in MyObjects) 
{ 
    using(var connection = new LinqToSqlDBContext()) 
    { 
     connection.StoredProc1(obj.Name); 
     connection.StoredProc2(obj.Name); 
    } 
} 

性能將最有可能是非常相似的。

0

嗯,實際上你的問題與Linq2Sql無關,因爲你使用的是存儲過程。您可以嘗試使用ado.net而不是使用datacontext來調用存儲過程。或許有一些性能上的優勢,但我不知道。

首先,由於您的兩個存儲過程具有相同的參數,因此您可以將它們合併到一個存儲過程中,這樣可能會花費一些開銷。

也可以像喬納斯H說的那樣:提供一個名字列表並且給SP打一次電話。

也許你可以通過在不同的線程中調用SP來完成一些並行處理,但這是Marc Gravell可能會發光的地方嗎?