2012-03-01 8 views
0

データベースから情報を取得するためにストアドプロシージャを使用しています。最初に、すべての親要素をフェッチして配列に保持し、親Idを使用してすべての関連する子をフェッチします。各親は150人の子供を持つことができます。約100の親要素があります。フェッチ操作のパフォーマンスを向上させる最善の方法は何ですか。現在、取得には13秒かかります。あなたは1 SQLのSELECT /ストアドプロシージャ内のすべてのデータを取得する(子データに参加するのいくつかの並べ替えを行う)し、その後親と子オブジェクトを移入する必要がありデータベースフェッチ操作のパフォーマンスを向上させる

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

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

んGetChildrenByParentId()別の接続を作成し、別のストアドプロシージャを呼び出しますか? – Jason

+0

はい別の接続を作成し、別のストアドプロシージャを呼び出します – azamsharp

+0

どのバージョンのSQL Serverを使用していますか? – Jason

答えて

4

:ここ

は、基本的なアルゴリズムです。今ではDBに100 * 150 = 15000リクエストがあります。これを1回のリクエストで行うことができれば、私は劇的なパフォーマンス効果が期待できます。

ブライアンコメントでそれを説明したように、それはRBAR、RowByAgonizingRowとして知られているに:) achronimeと同様に多く、ここではより多くのです:

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

+0

私はそれを試みることができると思います!おかげで – azamsharp

+1

+1アントニオ。 RBAR(google it)と呼ばれるものです。リレーショナルデータベースは、セットを取得するように設計されています。このコードは、1つのトランザクションで1000ドルを引き出す代わりに、銀行に行って1000ドル(1000トランザクション!)を払うことと比較することができます。 – brian

1

最初の、そして最も重要なステップで測定することですパフォーマンス。それはボトルネック、または.NETのSQL Serverですか?

また、データベースに戻さなければならない時間を最小限に抑える必要があるため、単一のストアドプロシージャで必要なすべてのデータを取得できる場合は、これが最適です。

あなたの質問から、SQL Serverのような問題は私に聞こえます。これをテストするには、SQLクエリアナライザからストアドプロシージャを実行し、既知の親IDにかかる時間を確認します。 SQLがデータをより速く取得できるようにするために、基になるテーブルにインデックスを追加するだけで済みます。可能であれば、ストアドプロシージャの実行計画を見てください。あなたは実行計画hereを読むことに関する良い記事を見つけることができます。

1

SQL Server 2008は簡単です。ユーザー定義のテーブルタイプを作成し、そのIDに親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プロパティはテーブル型の名前と一致する必要があることを覚えておいてください。

このメソッドでは、DBを1回呼び出すだけで、結果を反復処理するときには、選択リストにParentIDを含めて、各子を適切な親オブジェクトに一致させるようにする必要があります。

は、ここでより詳細にテーブルの種類を説明するための素晴らしいリソースです:http://www.sommarskog.se/arrays-in-sql-2008.html