Sql server 查询在SQL中运行不到一毫秒,但在实体框架中超时

Sql server 查询在SQL中运行不到一毫秒,但在实体框架中超时,sql-server,entity-framework,Sql Server,Entity Framework,以下linq到实体查询抛出 实体框架超时已过期。在此之前已过超时时间 操作完成或服务器没有响应 在把它列出来之后 ((System.Data.Objects.ObjectQuery)q)。ToTraceString()给了我: SELECT [Distinct1].[Taal] AS [Taal] FROM ( SELECT DISTINCT [Extent1].[Taal] AS [Taal] FROM [dbo].[ContactSet] AS [Extent1] WHERE ( EXI

以下linq到实体查询抛出

实体框架超时已过期。在此之前已过超时时间 操作完成或服务器没有响应

在把它列出来之后

((System.Data.Objects.ObjectQuery)q)。ToTraceString()给了我:

SELECT 
[Distinct1].[Taal] AS [Taal]
FROM ( SELECT DISTINCT 
[Extent1].[Taal] AS [Taal]
FROM [dbo].[ContactSet] AS [Extent1]
WHERE ( EXISTS (SELECT 
1 AS [C1]
FROM [dbo].[TemplategroepContact] AS [Extent2]
WHERE ([Extent1].[Autonummer] = [Extent2].[Contacts_Autonummer]) AND ([Extent2].[Templategroepen_Autonummer] = @p__linq__0)
)) AND ( NOT EXISTS (SELECT 
1 AS [C1]
FROM [dbo].[UitschrijvingenSet] AS [Extent3]
WHERE ([Extent1].[Autonummer] = [Extent3].[Contact_Autonummer]) AND ([Extent3].[Templategroep_Autonummer] = @p__linq__1)
))
)  AS [Distinct1]
来自tracestring的查询在sql management studio中运行不到1秒,但在实际列出它时超时?这又怎么可能呢

*更新:为query*添加了SQL分析器输出,运行速度与EF ToList()一样慢(>30秒)


暂时解决了这个问题,但我想那可能只是个临时工。解决方案

我知道这有点晚了,但我找到了答案

基本上,实体框架喜欢在默认情况下跟踪所有内容。如果不需要它(即不插入、更新或删除实体),请将其关闭以加快查询速度

如果您首先使用实体框架代码,您可以这样实现:

var q = (from contact
      in cDB.Contacts.AsNoTracking()
          .Where(x => x.Templategroepen.Any(z => z.Autonummer == templategroep.Autonummer) 
                            && !x.Uitschrijvings.Any(t => t.Templategroep.Autonummer == templategroep.Autonummer)) 
      select contact.Taal).Distinct();

我对EF6也有类似的问题。在EF中使用SqlQuery函数时,我得到了超时,尽管在ManagementStudio中以毫秒为单位执行查询。我发现这是由于我在EF查询中使用的一个sql参数的值造成的。为了清楚起见,下面是我使用过的类似SQL查询

SELECT * FROM TBL WHERE field1 > @p1 AND field2>@p2 AND field3<@p3

从TBL中选择*,其中field1>@p1和field2>@p2和field3我在EF6中观察到了这个问题

wait\u context.Database.SqlQuery(sql)
甚至在我的超时值被设置为60秒时也超时了。然而,在SSMS中执行完全相同的SQL(使用探查器确认我传入的SQL未被修改)在一秒钟内产生了预期的结果

执行sp_updatestats


为我解决了这个问题。

您需要添加一列作为唯一ID或密钥才能在EF中工作

您的连接字符串是否指向正确的位置?它返回多少行?打开您的SQL探查器,当您点击EF代码时,查看具体执行了什么。这将向您展示尝试执行什么样的SQLQuery,如果它正在执行的话。试试这种读入式sql,它会根据数据库返回1-10行,但它会访问+-10000行来收集这些数据。那么运行(DBCC FREEPROCCACHE)DBCC DROPCLEANBUFFERS有什么帮助呢?由于这是另一层的解决方案,我在SQL方面的经验并不丰富,但在阅读了这些命令的作用之后,我会认为查询的性能会下降。这似乎提供了一个线索,说明SQL Server可能正在缓存一个错误的执行计划。总而言之,我认为2DBCC命令修复是一个糟糕的长期解决方案,因为它们可能会影响其他查询的缓存执行计划。我遇到过这个问题,它导致EF中重复超时。在变量=0的情况下,我可以通过排除有问题的条件来解决这个问题,但我从来没有想到变量的值会以这种方式影响性能!我也遇到过这种情况。我们认为这是一个糟糕的执行计划。更新统计数据和重建索引修复了问题。我们添加了额外的代码,以便EF向查询添加额外的参数,以返回相同的结果。这是不同的,它使用了不同的执行计划,并在一秒钟内返回。因此,我们刷新了统计数据,删除了附加参数,它很快返回了结果。因此,我们每月在最忙的时间安排一次统计刷新(和索引重建)。
(DBCC FREEPROCCACHE)
DBCC DROPCLEANBUFFERS
var q = (from contact
      in cDB.Contacts.AsNoTracking()
          .Where(x => x.Templategroepen.Any(z => z.Autonummer == templategroep.Autonummer) 
                            && !x.Uitschrijvings.Any(t => t.Templategroep.Autonummer == templategroep.Autonummer)) 
      select contact.Taal).Distinct();
SELECT * FROM TBL WHERE field1 > @p1 AND field2>@p2 AND field3<@p3