概要: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に対して実行しています。