当直接sql立即返回时,为什么实体框架计数语句会超时?

时间:2014-02-20 17:32:48

标签: c# sql sql-server entity-framework

我们最近从数据库中删除了大量记录。删除后,从实体框架生成的此语句将超时。我们也为这些陈述设置了SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED。

实体框架代码

_emailSendResultsRepository.GetTable().Count(e => e.EmailId == email.Id && e.SendDate >= startDate);

生成此sql

SELECT 
[GroupBy1].[A1] AS [C1]
FROM ( SELECT 
        COUNT(1) AS [A1]
        FROM [dbo].[EmailSendResults] AS [Extent1]
        WHERE ([Extent1].[EmailId] = @p__linq__0) AND ( CAST( [Extent1].[SendDate] AS datetime2) >= @p__linq__1)
)  AS [GroupBy1]    
  • 如果我通过Sql management studio运行相同的语句,则返回 即刻。
  • 计算到同一张桌子而没有快速返回日期
  • 所有其他数据调用似乎都运行正常。

任何想法会导致超时?

2 个答案:

答案 0 :(得分:1)

它可能无法直接帮助您,但请结帐:

Which method performs better: .Any() vs .Count() > 0?

如果没有像你所描述的任何性能问题,我将关于表中记录的存在的检查从.Count()更改为.Any()。但是,当你真的不需要确切的计数时,这可能只会对你有所帮助。另外我需要提一下,我目前不删除大表中的任何记录,通常我会在检查.count()之前执行.where()子句。

当您将查询更改为.Where()时,您可以在收集.Count()的详细信息之前尝试检查.Any()

var queryList = _emailSendResultsRepository.GetTable()
    .Where(e => e.EmailId == email.Id)
    .Where(e.SendDate >= startDate)
    .ToList();

    if (queryList.Any())
    {
        ....
        queryList.Count()....
        ....
    }


msdn forums的帖子中 有提到:

“但是,即使SELECT COUNT(*)FROM Table在大型表上效率也相当低,因为SQL Server会进行全表扫描。”

答案 1 :(得分:1)

实际上MarkusEgle,你提供的声明:

var queryList = messages
.Where(t => t.LogTimeStamp >= fromDate)
.Where(t => t.LogTimeStamp <= toDate)
.Where(t => t.LogType != stateInfoNoAuditFile)
.OrderBy(m => m.LogID)
.ToList();

执行查询并获取结果,因此如果您随后调用queryList.Count它根本不接触数据库,它只计算列表中的对象(内存)。您应该删除ToList以获得所需的结果。