实体框架4.2 exec sp_executesql不使用索引(参数嗅探)

时间:2012-02-14 01:24:13

标签: entity-framework sql-server-2008-r2 sp-executesql parameter-sniffing

我遇到了针对SQL Server 2008 R2运行的实体框架(4.2)生成的简单SQL查询的一些主要性能问题。在某些情况下(但不是全部),EF使用以下语法:

exec sp_executesql 'DYNAMIC-SQL-QUERY-HERE', @param1...

在其他情况下,只需执行原始SQL,并将所提供的参数附加到查询中。我遇到的问题是使用sp_executesql执行的查询忽略了目标表上的所有索引,导致执行查询极差(通过检查SSMS中的执行计划来确认)。

经过一番研究,听起来这个问题可能是由'参数嗅探'引起的。如果我附加OPTION(RECOMPILE)查询提示,如下所示:

exec sp_executesql 'DYNAMIC-SQL-QUERY-HERE OPTION(RECOMPILE)', @param1...

使用目标表上的索引,并且查询执行速度非常快。我还尝试在数据库实例(http://support.microsoft.com/kb/980653)上切换用于禁用参数嗅探(4136)的跟踪标志,但这似乎没有任何效果。

这给我留下了几个问题:

  1. 是否有将OPTION(RECOMPILE)查询提示附加到实体框架生成的SQL?
  2. 无论如何阻止Entity Framework使用exec sp_executesql,而只是运行原始SQL?
  3. 还有其他人遇到这个问题吗?还有其他提示/提示吗?
  4. 其他信息:

    1. 我确实通过SSMS重新启动了数据库实例,但是,我将尝试从服务管理控制台重新启动该服务。
    2. 参数化设置为SIMPLE(is_parameterization_forced:0)
    3. 针对特殊工作负载进行优化具有以下设置
      • 值:0
      • 最小:0
      • 最大值:1
      • value_in_use:0
      • is_dynamic:1
      • is_advanced:1
    4. 我还应该提一下,如果我通过服务管理控制台重新启动SQL Server服务,在使用下面的脚本启用跟踪标志4136之后,实际上似乎清除了跟踪标志......也许我应该以不同的方式这样做。 ..

      DBCC TRACEON(4136,-1)
      

2 个答案:

答案 0 :(得分:6)

<强> TL;博士

update statistics


我们有一个delete查询,其中包含一个参数(主键),通过EF和sp_executesql调用时需要大约7秒才能完成。手动运行查询,并将参数嵌入到sp_executesql的第一个参数中,使查询快速运行(~0.2秒)。添加option (recompile)也有效。当然,由于使用EF,我们无法使用这两种解决方法。

可能由于级联外键约束,长时间运行的查询的执行计划是,呃...,巨大的。当我查看SSMS中的执行计划时,我注意到在某些情况下不同步骤之间的箭头比其他情况更宽,可能表明SQL Server无法做出正确的决策。这让我想到了统计数据。我查看了执行计划中的步骤,以查看可疑步骤中涉及的表格。然后我为该表运行了update statistics Table。然后我重新运行了错误的查询。我再次重新跑了。再一次只是为了确保。有效。我们的性能恢复正常。 (仍然比非sp_executesql表现稍差,但嘿!)

事实证明,这只是我们开发环境中的一个问题。 (这是一个很大的问题,因为它使我们的集成测试永远存在。)在我们的生产环境中,我们有一份工作,定期更新所有统计数据。

答案 1 :(得分:5)

此时我会建议:


将ad hoc workload for optimize设置为true。

EXEC sp_configure 'show advanced', 1;
GO
RECONFIGURE WITH OVERRIDE;
GO
EXEC sp_configure 'optimize for ad hoc', 1;
GO
RECONFIGURE WITH OVERRIDE
GO
EXEC sp_configure 'show advanced', 0;
GO
RECONFIGURE WITH OVERRIDE;
GO

如果一段时间后这个设置似乎没有帮助,那么我才会尝试追踪标志的额外支持。这些通常作为最后的手段保留。通过SQL Server配置管理器使用命令行设置跟踪标志,而不是在查询窗口中使用全局标志。见http://msdn.microsoft.com/en-us/library/ms187329.aspx