3

現在、ビジネスオブジェクトにデータを入力する方法は、以下のスニペットのようなものを使用しています。

using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.CDRDatabase))
{
    using (SqlCommand comm = new SqlCommand(SELECT, conn))
    {
        conn.Open();

        using (SqlDataReader r = comm.ExecuteReader(CommandBehavior.CloseConnection))
        {
            while (r.Read())
            {
                Ailias ailias = PopulateFromReader(r);
                tmpList.Add(ailias);
            }
        }
    }
}

private static Ailias PopulateFromReader(IDataReader reader)
{
    Ailias ailias = new Ailias();

    if (!reader.IsDBNull(reader.GetOrdinal("AiliasId")))
    {
        ailias.AiliasId = reader.GetInt32(reader.GetOrdinal("AiliasId"));
    }

    if (!reader.IsDBNull(reader.GetOrdinal("TenantId")))
    {
        ailias.TenantId = reader.GetInt32(reader.GetOrdinal("TenantId"));
    }

    if (!reader.IsDBNull(reader.GetOrdinal("Name")))
    {
        ailias.Name = reader.GetString(reader.GetOrdinal("Name"));
    }

    if (!reader.IsDBNull(reader.GetOrdinal("Extention")))
    {
        ailias.Extention = reader.GetString(reader.GetOrdinal("Extention"));
    }

    return ailias;
}

誰かがこのようなものでパフォーマンスを改善する方法の提案がありますか?PopulateFromReaderには、一部のタイプでは、オブジェクトを完全に設定するために、より多くのデータベースルックアップが含まれていることに注意してください。

4

5 に答える 5

7

明らかな変更の1つは、この種のステートメントを置き換えることです。ailias.AiliasId = reader.GetInt32(reader.GetOrdinal( "AiliasId"));

ailias.AiliasId = reader.GetInt32(constAiliasId);

ここで、constAiliasIdは、フィールドAiliasIdの序数を保持する定数です。

これにより、ループの各反復での通常のルックアップが回避されます。

于 2009-07-27T11:02:50.473 に答える
5

データ量が多い場合、膨大なリストを作成するオーバーヘッドがボトルネックになる可能性があります。その場合は、ストリーミング オブジェクト モデルを使用する方が効率的です。すなわち

public IEnumerable<YourType> SomeMethod(...args...) {
    using(connection+reader) {
        while(reader.Read()) {
            YourType item = BuildObj(reader);
            yield return item;
        }
    }
}

消費するコード ( foreachetc 経由) には、(一度に) 処理するオブジェクトが 1 つしかありません。リストを取得したい場合は、( new List<SomeType>(sequence)、または .NET 3.5: を使用してsequence.ToList()) 取得できます。

これには、さらにいくつかのメソッド呼び出し (シーケンスごとの追加のMoveNext()/Currentの後ろに隠されている項目foreach) が含まれますが、データベースなどのプロセス外のデータがある場合は、これに気付くことはありません。

于 2009-07-27T11:06:25.567 に答える
1

あなたのコードは、多くのビジネス オブジェクト ロード関数とほとんど同じに見えます。DAL のパフォーマンスの問題が疑われる場合、いくつかのことを調べます。

  1. DB へのホップアウトの回数は? 接続頻度を減らし、複数の結果セット (ストアド プロシージャを使用) を使用して、より大きなデータ チャンクを戻す方法はありますか?とその子。脆弱な SQL (一致する必要がある並べ替え順序など) や、DataReader を巡回するトリッキーなループに遭遇する可能性がありますが、複数の DB トリップよりも最適であることがわかりました。

  2. パケット スニファー/ネットワーク モニターを起動して、ネットワーク上で送信されているデータの量を正確に確認します。一部の結果セットが非常に大きいことに驚くかもしれません。もしそうなら、問題にアプローチする別の方法を考えるかもしれません。いくつかの子データの読み込みを遅延/遅延するように。

  3. 求めているすべての結果を使用していることを確認してください。たとえば、SELECT * FROM (30 個のフィールドが返される) から単純に SELECT Id, Name FROM (それが必要な場合) に移行すると、大きな違いが生じる可能性があります。

于 2009-07-27T11:26:53.327 に答える
0

本当の問題は、あなたが言及したオブジェクトごとの複数のルックアップである可能性があります。それらすべてを単一のストアドプロシージャに入れることができるかどうかをよく調べましたか?

于 2009-07-27T12:31:44.427 に答える
0

AFAIK、それはそれが得るのと同じくらい速いです。おそらく、速度が遅いのはSQLクエリ/サーバーにあります。またはどこか他の場所。

于 2009-07-27T11:00:47.030 に答える