8

概要:EF4クエリのコンパイル時間が12秒以上で問題が発生しています。キャッシュされたクエリは、これまでのところしか取得できません。実際にコンパイル時間を短縮する方法はありますか?私たちが間違っているかもしれない何かを探すことができますか?ありがとう!

WCFサービスで公開されるEF4モデルがあります。エンティティタイプごとに、参照されている子オブジェクトの数を含む、表示/編集用のエンティティ全体をフェッチして返すメソッドを公開します。

1つの特定のエンティティについて、関連するすべてのデータを返すには、31個のテーブル/サブテーブルを.Include()する必要があります。残念ながら、これによりEFクエリのコンパイルが非常に遅くなります。コンパイルに12〜15秒かかり、7,800行の300Kクエリが作成されます。これはWebUIのバックエンドであり、それよりもスッキリする必要があります。

これを改善するために私たちにできることはありますか?CompiledQuery.Compile this-これは最初の使用まで何の作業も行わないため、2回目以降の実行に役立ちますが、最初の使用も遅くならないようにお客様は神経質になっています。同様に、WebサービスをホストしているIISアプリプールがリサイクルされると、キャッシュされたプランは失われますが、これを最小限に抑えるためにライフタイムを増やすことができます。また、これを事前にプリコンパイルしたり、EFでコンパイルされたクエリキャッシュをシリアル化する方法がわかりません(リフレクションのトリックはありません)。CompiledQueryオブジェクトには、キャッシュへのGUID参照のみが含まれているため、これが私たちが本当に気にかけているキャッシュです。(これを書き出すと、app_startupからバックグラウンドで何かを開始して、すべてのクエリを実行してコンパイルすることができます-それは安全ですか?)

ただし、その問題を解決したとしても、検索対象のパラメーターに基づいてLINQ-to-Entities句を使用して動的に検索クエリを構築します。SQLジェネレーターは、移動できるほど十分に機能しないと思います。そのすべてのロジックをSQLレイヤーに組み込むため、検索クエリを事前にコンパイルすることはできないと思います。検索データの結果に使用されるテーブルが少なく、コンパイルにかかる時間は12〜15秒ではなく3〜4秒であるため、これはそれほど深刻ではありませんが、顧客はそれでもエンドユーザーには実際には受け入れられないと考えています。

したがって、クエリのコンパイル時間をなんとかして短縮する必要があります。何か案は?

  • プロファイリングは開始する場所としてELinqQueryState.GetExecutionPlanを指しており、それに踏み込もうとしましたが、実際の.NET 4ソースが利用できないと、それほど遠くまで行くことができず、Reflectorによって生成されたソースではいくつかに踏み込むことができません。関数またはそれらにブレークポイントを設定します。
  • プロジェクトは.NET3.5からアップグレードされたので、何か問題があった場合に備えて、EF4でEDMXを最初から再生成してみましたが、それは役に立ちませんでした。
  • ここで宣伝されているEFProfユーティリティを試しましたが、これには役立たないようです。私の大きなクエリはとにかくそのデータコレクターをクラッシュさせます。
  • 生成されたクエリをSQLパフォーマンスチューニングで実行しましたが、すでに100%のインデックス使用率があります。クエリジェネレータの問題を引き起こすデータベースに問題はありません。
  • 実行プランコンパイラに何かO(n ^ 2)がありますか?これを一度に32個のテーブルすべてではなく、個別のデータロードのブロックに分割すると役立つ可能性がありますか?EFを遅延読み込みに設定しても効果はありませんでした。
  • プレリリースのO'ReillyJulieLerman EF4の本を購入しましたが、「クエリのコンパイル」以外に役立つものは何も見つかりません。

32個のテーブルにわたって単一の選択を生成するのに12〜15秒かかる理由がわかりません。そのため、改善の余地があると楽観視しています。

提案をありがとう!重要な場合はSQLServer2008に対して実行し、RTMVS2010を使用するXP/7/サーバー2008R2に対して実行しています。

4

5 に答える 5

8

クエリを簡単にします。真剣に; クエリの複雑さとコンパイル時間の間にはほぼ線形の関係があります。多くの場合、2つの単純なクエリは、1つの本当に複雑なクエリよりもはるかに高速です(プリコンパイルされている場合でも!)。速度が最終目標である場合は、最速のオプションを選択してください。

于 2010-04-29T18:45:31.363 に答える
4

SQLを完全に制御できる、より複雑なクエリのビューを作成できます。次に、そのビューをデータモデルに含めます。

于 2010-04-30T11:17:36.263 に答える
1

これはあなたが探している答えではない可能性がありますが、簡単な回避策として、最初の(顧客)呼び出しではなく、Webアプリケーションが初期化されたときにCompiledQuery.Compileを実行します(Webアプリケーションへのダミー呼び出しを行います) 。

于 2010-04-29T18:04:25.077 に答える
1

http://www.iis.net/download/ApplicationWarmupを使用してみることができます。 現在ベータ版ですが、使用することも検討しています。

于 2010-04-30T15:45:23.183 に答える
1

nqueriesを見てください。これは、アプリケーションの起動時に生成されるプリコンパイル済みのクエリを使用します。

編集:EF5に切り替えたため、NQueriesはDbContextに切り替えたため、コンパイル済みクエリをサポートしなくなりました。それでも確認したい場合は、1.03リリースのソースコードを参照してください。これは引き続きObjectContextベースであり、コンパイル済みクエリをサポートします。

于 2011-04-12T07:52:49.707 に答える