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