Performance 如何防止EF Linq为变量和常量生成不同的查询?

Performance 如何防止EF Linq为变量和常量生成不同的查询?,performance,linq,entity-framework,query-optimization,Performance,Linq,Entity Framework,Query Optimization,我有一个Linq查询,它使用硬整数值在大约一分钟内(第一次)返回LinqPad。 然而,当我将这些硬整数值转换为局部变量时,这需要花费很长时间(超过20分钟) 我的基本问题是: 为什么/如何使用不同的SQL查询会导致如此多的延迟 我可以阻止这种不同的SQL查询吗 在我试图解决这个问题的过程中(见下文),我遇到了以下问题: 如何使用defaultqueryplanchachingset或启用计划缓存 如何抑制/防止查询编译/优化 如何验证我是否正在使用EF5 这个问题似乎已经被注意到了,答

我有一个Linq查询,它使用硬整数值在大约一分钟内(第一次)返回LinqPad。 然而,当我将这些硬整数值转换为局部变量时,这需要花费很长时间(超过20分钟)

我的基本问题是:

  • 为什么/如何使用不同的SQL查询会导致如此多的延迟
  • 我可以阻止这种不同的SQL查询吗
在我试图解决这个问题的过程中(见下文),我遇到了以下问题:

  • 如何使用
    defaultqueryplanchachingset
    启用计划缓存
  • 如何抑制/防止查询编译/优化
  • 如何验证我是否正在使用EF5
这个问题似乎已经被注意到了,答案也在这个问题上。我也有这个查询差异,我看到一个额外的子选择(和一些额外的连接)。查询使用参数(
[Extent6].[SomeThingId]=@p\uu linq\uu 0
)代替硬整数值(
4=[Extent6].[SomeThingId]

然而,我不知道为什么这会是一个问题,我如何才能防止它。 (我理解在提供查询或数据库布局时,答案可能更容易,但这类敏感材料,我的问题保持不变…)

我假设问题来自于使用参数时编译/执行计划中的一些“优化”。我试着使用:

我无法实现这一点,因此我试图找出是否可以使用同样提到的[
ObjectQuery.EnablePlanCaching=false;
],但我找不到在哪里/如何使用它。(我无法将我的
IQueryable
转换为
ObjectQuery
,也无法转换为我的上下文。)有人知道如何使用
DefaultQueryPlanachingSetting
EnablePlanCaching

我尝试的另一件事是从常量值Linq中获取SQL,并在其中引入一些SQL变量。这也很好,所以我尝试在一个存储过程中转换它,我可以从EF调用它。但是现在存储过程也需要很长时间才能运行

我(也)在想。(这是我第一个使用Linq、EntityFramework和ASP.MVC的项目。)但我在另一个问题中谈到了这一点

更新:我更改了“常规”存储过程:

SELECT ... WHERE @Id  = [Extent6].[SomeThingId] ...
使用动态SQL语句插入存储过程:

@sql = 'SELECT ... WHERE ' + CAST(@Id AS VARCHAR) + ' = [Extent6].[SomeThingId] ...';
EXEC (@sql);
有了这个“动态”存储过程,我可以很快得到结果。而且,由于参数将相当恒定(它们可能会在一天一次和一周一次之间变化),我认为这种缺乏优化/缓存的情况对性能来说是可以接受的。
(然而,我不喜欢将业务逻辑放在存储过程中。)

我找到了Stuart Leeks的这篇文章。它提到,
DefaultQueryPlanachingSetting
没有通过EF5的候选发行版,您需要在ObjectSet上设置
EnablePlanCaching
属性。它也有一个简单的例子和一个方便的扩展方法的建议。我将引用Stuart Leeks的例子,因为“常规”还没有提供。你可以在他的博客上查看扩展方法

ObjectQuery<Customer> customersNoCache = context.Customers;
customersNoCache.EnablePlanCaching = false;
var query1 = from customer in context.Customers
             where customer.Country == "UK"
             select customer;
但是生成的SQL仍然包含参数优化。我猜想,<代码> EnabyLink PultCache <代码>只会抑制从LINQ生成SQL的缓存,它甚至不考虑SQL方面的缓存?


(不幸的是,我没有时间进一步重新搜索/测试。我执行了“动态”存储过程,并完成了此项目。)

您可能正在使用C执行查询,而不是发布您的查询。我不认为使用C执行是问题所在。我认为我关于存储过程中动态查询的更新也说明了这一点。我仍然怀疑我是否应该采用这种不合法的“动态程序”。
ObjectQuery<Customer> customersNoCache = context.Customers;
customersNoCache.EnablePlanCaching = false;
var query1 = from customer in context.Customers
             where customer.Country == "UK"
             select customer;
ObjectContext lObjectContext = ((IObjectContextAdapter)this).ObjectContext;
ObjectQuery<Customer> lDocCatgNoCache = lObjectContext.CreateObjectSet<Customer>();