我有一个 Linq 查询,它使用硬整数值在大约一分钟(第一次)内返回 LinqPad。但是,当我将这些硬整数值转换为局部变量时,需要很长时间(超过 20 分钟)。
我的基本问题是:
- 为什么/如何不同的 SQL 查询会导致这么多延迟?
- 我可以防止这种不同的 SQL 查询吗?
在我试图解决这个问题时(见下文),我遇到了这些问题:
- 我该如何使用
DefaultQueryPlanCachingSetting
orEnablePlanCaching
? - 如何抑制/防止查询编译/优化?
- 如何验证我是否在使用 EF5?
查询差异似乎已经被注意到,并且在对该问题的回答中解释了原因。我也有这个查询差异,我看到一个额外的子 SELECT(和一些额外的 JOIN)。并且查询使用参数 ( [Extent6].[SomeThingId] = @p__linq__0
) 而不是硬整数值 ( 4 = [Extent6].[SomeThingId]
)
但是,我不确定为什么这会是一个问题,以及如何防止它。(我知道在提供查询或数据库布局时答案可能会更容易,但是这种敏感材料,我的问题仍然是一样的......)
我假设问题出在使用参数时编译/执行计划中的一些“优化”。我正在尝试使用此建议来打开 L2E 的自动编译:
db.ContextOptions.DefaultQueryPlanCachingSetting = false;
//(db as IObjectContextAdapter).ObjectContext.DefaultQueryPlanCachingSetting = false;
我无法让它工作,所以我试图找出我是否可以使用也提到的 [ ObjectQuery.EnablePlanCaching = false;
],但我找不到在哪里/如何使用它。(我无法将我IQueryable
的转换为ObjectQuery
,也无法转换为我的上下文。)有人知道如何使用DefaultQueryPlanCachingSetting
orEnablePlanCaching
吗?
我尝试的另一件事是从常量值 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);
使用这个“动态”存储过程,我确实得到了非常快速的结果。而且由于参数将是相当恒定的(它们可能会在每天一次和每周一次之间变化),我认为这种缺乏优化/缓存对于性能来说是可以的。(但是,我不喜欢将业务逻辑放在存储过程中。)