0

ハード整数値を使用して約 1 分 (初回) で LinqPad に返される Linq クエリがあります。ただし、これらのハード整数値をローカル変数に変換すると、永遠に (20 分以上) かかります。

私の基本的な質問は次のとおりです。

  • なぜ/どのように別のSQLクエリがこれほどの遅延を引き起こすのでしょうか?
  • この異なる SQL クエリを防ぐことはできますか?

これを解決しようとして(下を参照)、次の質問に出くわしました。

  • またはをどのように使用できますDefaultQueryPlanCachingSettingEnablePlanCaching?
  • クエリのコンパイル/最適化を抑制/防止するにはどうすればよいですか?
  • EF5 を使用しているかどうかを確認するにはどうすればよいですか?

クエリの違いはすでに気づいているようで、その理由はその質問への回答で説明されています。また、追加のサブ SELECT (およびいくつかの追加の JOIN) が表示されるクエリの違いもあります。また、クエリは[Extent6].[SomeThingId] = @p__linq__0、ハード整数値 ( 4 = [Extent6].[SomeThingId])の代わりにパラメーター ( ) を使用します。

ただし、なぜこれが問題になるのか、どうすれば回避できるのかはわかりません。(クエリまたはDBレイアウトを提供すると答え簡単になる可能性があることは理解していますが、この種の機密資料であり、私の質問は同じままです...)

パラメータを使用するときのコンパイル/実行計画の「最適化」に問題があると想定していました。この提案を使用して、 L2E の自動コンパイルをオフにしようとしていました:

 db.ContextOptions.DefaultQueryPlanCachingSetting = false;
 //(db as IObjectContextAdapter).ObjectContext.DefaultQueryPlanCachingSetting = false;

これを機能させることができなかったので、言及された [ ObjectQuery.EnablePlanCaching = false;] を使用できるかどうかを調べようとしましたが、どこで/どのように使用するかを見つけることができませんでした。(私は、または私のコンテキストIQueryableにキャストすることはできませんObjectQuery。) or の使用方法を知っている人はいますDefaultQueryPlanCachingSettingEnablePlanCaching

私が試したもう1つのことは、定数値LinqからSQLを取得し、そこにいくつかのSQL変数を導入することでした。それもうまくいったので、EFから呼び出すことができるストアドプロシージャでこれを回してみました。しかし、ストアド プロシージャの実行にも非常に時間がかかります。

本当に EntityFramework 5を持っているかどうかも(また)疑問に思っています。(これは、Linq、EntityFramework、および ASP.MVC を使用した最初のプロジェクトです。)しかし、別の質問でそれを変えました。

更新:「通常の」ストアド プロシージャを変更しました。

SELECT ... WHERE @Id  = [Extent6].[SomeThingId] ...

動的 SQL ステートメントを使用してストアド プロシージャに変換します。

@sql = 'SELECT ... WHERE ' + CAST(@Id AS VARCHAR) + ' = [Extent6].[SomeThingId] ...';
EXEC (@sql);

この「動的な」ストアド プロシージャを使用すると、非常に迅速に結果を得ることができます。また、パラメータはかなり一定であるため (おそらく 1 日 1 回から 1 週間に 1 回の間で変化します)、この最適化/キャッシュの欠如はパフォーマンスにとって問題ないと思います。(ただし、ビジネス ロジックをストアド プロシージャに入れるのは嫌いです。)

4

1 に答える 1

1

自動クエリ コンパイルを制御する Entity Framework 5に関する Stuart Leeks によるこの投稿を見つけました。DefaultQueryPlanCachingSettingEF5 の Release Candidate を通過できなかったため、EnablePlanCaching代わりに ObjectSets にプロパティを設定する必要があると述べています。また、簡単な例と便利な拡張方法の提案も含まれています。「通常の」 MSDNにはまだ提供されていないため、Stuart Leeks の例を引用します。拡張方法については、彼のブログを参照してください。

ObjectQuery<Customer> customersNoCache = context.Customers;
customersNoCache.EnablePlanCaching = false;
var query1 = from customer in context.Customers
             where customer.Country == "UK"
             select customer;

編集:実際には、 aから anに取得するためにDbSetObjectQueryさらにコードを追加する必要がありました。前のCustomer-example に沿って、これは次のようになります。

ObjectContext lObjectContext = ((IObjectContextAdapter)this).ObjectContext;
ObjectQuery<Customer> lDocCatgNoCache = lObjectContext.CreateObjectSet<Customer>();

ただし、生成された SQL にはまだパラメーターの最適化が含まれています。私の推測では EnablePlanCaching、Linq から SQL を生成するためのキャッシュのみを抑制し、SQL 側のキャッシュも考慮していないのでしょうか?

(残念ながら、これ以上調査/テストする時間がありませんでした。「動的な」ストアド プロシージャの実装に取り​​組み、このプロジェクトを終了しました。)

于 2013-04-08T07:33:20.853 に答える