2011-07-19 8 views
3

私はデータベースからレコードを取り出すコードをいくつか持っています。次に、単純な比較を行い、レコードが特定のモジュールとレスポンスに一致するかどうかを確認してから、カウントを使用して統計を表示します。残念ながら、それはデータベースの1000レコードを超えるものになると非常に遅いです。foreachループを最適化する

nHibernateでは、最初のクエリ時間にちょっとした助けとなるレイジーローディングを有効にしましたが、少し深く掘り下げていく必要があるこの部分に到達すると、多くの速度が低下します。私は問題は、これらの統計情報を得るために、多くの異なるテーブルからデータを取り出すことだと思います。

foreachループを使用する代わりに、linqステートメントを書くことでこれをスピードアップできるはずですが、私はいくつかの試みを行いました。誰かが私を正しい方向に向けるのを助けることができるかどうか疑問に思っていた。または、良いLinqのチュートリアルや本には私が話題に少し知っているから

また、私は同じようなケースでは、人々はSQL Serverにルックアップに使用されている別のテーブルを作成するジョブを入れてお勧めしますが、可能ならばこれを避けてください。

ここにコードがあります。

int modules = 0; 
var sessionsWithPullHits = from session in m_sessions where session.PullHits.Count > 0 select session; 

foreach (ISession<PullHitRecord, PushHitRecord> session in sessionsWithPullHits) 
{ 
    foreach (var pullHit in session.PullHits) 

    if ((pullHit.Module == _Module) && (pullHit.Response == _response)) 
    { 
     modules++; 
    } 
} 

誰かが助けてくれたことに感謝します。

+1

ところで、よく書かれた質問。ようこそstackoverflowへ! –

答えて

4

LINQ:

var modules = (from session in m_sessions 
       from pullHit in session.PullHits 
       where pullHit.Module == _Module && pullHit.Response == _response 
       select pullHit).Count(); 

注、私はこれをSQLに変換する方法をわからないんだけど、それは1つのLINQ文のだ、そう動作するはずです。

+0

助けてくれてありがとう、これは完全にforeachループを置き換えるために動作します。私はパフォーマンスがforeachループ上にわずかに増加したので、別のテーブルを作成するルートを下げる必要があるかもしれないと思います。 – Neil

+0

私の提案では、あなたのC#コードは非効率な部分ではない可能性があります。代わりにあなたのDBコードを見てください。 –

1

あなたがしようとしているのは、セッション数を取得するだけの場合、SPに_Moduleと_responseを渡して、DBにカウントさせてカウントだけを返すようにしてください。

もちろん、もっとやっているのなら、これは当てはまりません。しかし、あなたがしていない多くの功績を返すことは効率的ではありません。

2

@George Duckettの答えは、foreachコードをLINQに置き換えるためのものです。また、あなたはそうのような流暢な構文で彼の同じクエリを表現することができます。

var modules = m_sessions 
.SelectMany(session => session.PullHits, 
      (session, pullHits) => new { pullHits = pullHits }) 
.Where(session => session.pullHits.Module == _Module && 
        session.pullHits.Response == _response) 
.Count(); 

とてもきれいではありませんが、結果としてILが小さいし、あなたにわずかに良い結果をもたらすことがあります。また、このバージョンではコードが少し小さくなり、小さな利益をもたらすかもしれません。テストおよび参照:

var modules = m_sessions 
    .Select(session => session.PullHits 
     .Count(pullHit => pullHit.Module == _Module && 
         pullHit.Response == _response)) 
    .Sum(); 

免責事項:私は時期尚早の最適化をサポートしていませんが、私は私があなたのテーブルにインデックスを管理するに見てね

0

:-)それを有効にします。結合で使用される列に索引を追加すると、パフォーマンスに著しい影響を与える可能性があります。このreferenceを参照してください。

他のSQLパフォーマンス調整のヒントの一覧を示します。Performance Tuning SQL Server Joins