2012-03-01 58 views
0

我正在使用存儲過程從數據庫中獲取信息。首先,我獲取所有的父元素,並將它們保存在數組中,然後使用父ID來獲取所有相關的子元素。每個家長可以有150個孩子。大約有100個父元素。提高抓取操作性能的最佳方法是什麼?目前需要13秒才能檢索。提高數據庫提取操作的性能

這是基本的算法:

while(reader.read()) 
{ 
    Parent p = new Parent(); 
    // assign properties to the parent 

    p.Children = GetChildrenByParentId(parent.Id);  
} 
+1

不GetChildrenByParentId()創建另一個連接,並調用另一個存儲過程? – Jason 2012-03-01 15:45:05

+0

是的,它創建一個單獨的連接並調用一個單獨的存儲過程 – azamsharp 2012-03-01 15:45:39

+0

您正在使用哪個版本的SQL Server? – Jason 2012-03-01 15:48:28

回答

4

你應該得到一個SQL選擇/存儲過程的所有數據(做一些參加兒童的數據),然後填充家長和孩子的對象。現在你在DB和I上有100 * 150 = 15000個請求,如果你可以用一個請求來做到這一點,我會期望有戲劇性的效果。

布賴恩在評論中提到它,被稱爲RBAR,RowByAgonizingRow :) 像achronime很多,這裏是更多:

https://www.simple-talk.com/sql/t-sql-programming/rbar--row-by-agonizing-row/

+0

我想我可以試試!謝謝 – azamsharp 2012-03-01 15:52:26

+1

+1 Antonio。這就是所謂的RBAR(谷歌它)。關係數據庫被設計來檢索集合。這個代碼可以比較去銀行並且提取1000美元(1000次交易!),而不是用1次交易提取1000美元。 – brian 2012-03-01 15:56:28

1

第一個也是最重要的一步是測量性能。 SQL Server是瓶頸還是.NET?另外,您需要儘量減少返回到數據庫的時間,因此如果您可以在單個存儲過程中檢索所需的所有數據,那將是最佳選擇。

從你的問題,這聽起來像它是SQL Server是問題。爲了測試這個,從SQL Query Anylizer運行你的存儲過程,並且看看一個已知的父ID需要多長時間。我敢打賭,您只需將一些索引添加到基礎表中即可使SQL更快地獲取數據。如果可能,請查看存儲過程的執行計劃。你可以找到一篇關於閱讀執行計劃here的好文章。

1

SQL Server 2008非常簡單,可以創建一個用戶定義的表類型並將父類型ID列表傳遞給該類型,或者您可以使用您首先獲得這些父類型ID的邏輯並加入到表中擁有兒童數據。

要創建的表類型,你讓這樣的事情:

CREATE TYPE [dbo].[Int32List] 
AS TABLE (
[ID] int NOT NULL 
); 
GO 

而且你的存儲過程是這樣的:

CREATE PROCEDURE [dbo].[MyStoredProc] 
@ParentIDTable [dbo].[Int32List] READONLY 
AS 
--logic goes here 
GO 

你從這樣的C#代碼調用程序:

DataTable ParentIDs = new DataTable(); 
ParentIDs.Columns.Add("ID", typeof(int)); 

SqlConnection connection = new SqlConnection(yourConnectionInfo); 
SqlCommand command = new SqlCommand("MyStoredProc", connection); 
command.CommandType = CommandType.StoredProcedure; 
command.Parameters.Add("@ParentIDTable", SqlDbType.Structured).Value = ParentIDs; 
command.Parameters["@ParentIDTable"].TypeName = "Int32List"; 

這種方式很好,因爲這是一個很好的方式來有效地傳遞一個列表v到SQL Server的線索並將其視爲一張表。我使用的表格類型遍及我的應用程序,我想將一個值的數組傳遞給存儲過程。請記住,C#DataTable中的列名需要與您創建的表類型中的列名匹配,並且TypeName屬性需要與表類型的名稱匹配。

使用此方法,您只會對數據庫進行1次調用,並且在遍歷結果時,還應確保將ParentID包括在選擇列表中,以便您可以將每個子對象與適當的父對象進行匹配。

這裏有一個很好的資源,更詳細地解釋表類型:http://www.sommarskog.se/arrays-in-sql-2008.html