2013-05-06 8 views
5

非常に単純なEFクエリを実行して、ユーザーが有効かどうかを判断するログインページがあります。最初の実行では、このクエリーは実行に約6秒かかります。その後の実行では、1秒よりもはるかに短い時間がかかります。エンティティフレームワークのクエリを高速化するために、それらを初期化するにはどうすればよいですか?

私はApplication Auto-Startを使用して話した記事を見てきました。私の質問はこれです。実際にクエリを呼び出さずにキャッシュを実行するためにこのクエリをトリガーする方法はありますか?ダミーの引数セットでクエリを呼び出すだけですか?

EDIT:私が6秒と言うとき、私はクエリを取得するのにかかる時間を指しています。

return from contact in _context.Contacts 
      where contact.District == Environment.District && 
      contact.ContactId == (contactID ?? contact.ContactId) 
      select contact; 

これは、のSQLServer 2008年であり、私はそれが返すSQLと持続時間を確認するためのプロファイラを実行しました:コードは、この(ノートこの場合にはcontactIDがNULL可能でint型とnullに設定されている)のようになります最終的に実行されるクエリは41msです。クエリがSQLに到達する前に、6〜7秒の遅延が発生します。私はそれが私に同時に起こっているかもしれない他の事柄の詳細を私に与えることができるかどうかを見るために今覗いてみようとしています。

+0

私は、プロファイリングをいくつか行い、遅延が実際にどこで発生しているのかを調べることは価値があるかもしれないと思います。 –

+0

EFのオーバーヘッドはかなり軽く、おそらく問題ではありません。おそらくGlimpse(NuGetパッケージ)のようなものをインストールして、本当に何が原因であるかを見てください。あなたは本当に間違っている(ブートストラップされたアドイン?)他のイベントが発生している可能性があります。 –

+0

@RobertHarvey SQLプロファイリングまたは.NETプロファイリングを意味しますか? – Mykroft

答えて

2

これは実際には「コールドクエリー」と呼ばれるように聞こえます。コールドクエリの主なパフォーマンスボトルネックは、アプリケーションのAppDomainごとに1回実行される「View Generation」です。通常は、最初のクエリが遅くなり、その後のクエリが高速になります。

これは必ずしも遅くなるクエリである必要はありません。アプリケーションでEFを使用して最初に行う操作が、挿入が遅い場合。あるいは、データベースに全く触れないAttachさえも遅いでしょう。 (ちなみに良い簡単なテストケースです:アプリケーションの開始にcontext.Users.Attach(new User())を追加し、デバッガでその行をどれぐらいの時間が経過するかを見てください)。

すべての場合、内部データ構造をメモリ - ローカルクエリ "views"(データベーステーブルビューとは関係ありません) - AppDomainごとに1回実行されます。

ビュー生成の詳細はhere、詳細はとなります。これらのビューをビルドプロセスの一部として、およびデプロイメント前に「事前生成」する方法についても説明しています。

代替方法は、Webアプリケーションの起動を定期的に開始することです(たとえば、サイトにヒットするプロセスによって) 。アプリケーションでは、あなたが上記のいずれかのダミークエリまたはAttach事を実行するか、または手動でEFの初期化を呼び出します開始:

using (var context = new MyContext()) 
{ 
    context.Database.Initialize(false); 
} 

編集

私は最後の解決策を忘れてしまいました。ちょうど6または7秒を無視してください。あなたのサイトが有名になって合理的なトラフィックがある場合、IISワーカープロセスがAppDomainをめったにシャットダウンしないため、このようなコールドクエリーは起こりにくいでしょう。そのようなシャットダウンが直前に起こった夜にサイトを襲った時折のユーザーは、遅れに気づくためにもあまりにも疲れているでしょう。

+1

これはエンタープライズコーディングであり、「有名になった」ことは解決策としては機能しません:)。しかし、私はアプリケーションの自動スタートのものと組み合わせた初期化の呼び出しが私の問題を解決するかもしれないと思う。私は今日それをテストします。ありがとう。 – Mykroft

+0

"あまりにも疲れて、遅延に気付くことさえありません。 - 別の時間帯にいない限り。 – mayu

関連する問題