枚举EF存储过程结果

时间:2014-12-11 19:29:05

标签: c# sql-server entity-framework

我正在调用一个返回大约650行的简单存储过程。有几个连接,程序大约需要5-6秒。没问题。

然而,列举结果大约需要一分钟才能完成。

using (var context = new DBContext())
{
    var results = context.GetResults(param); //5-6 seconds
    var resultList = results.ToList(); //1 minute+
}

我没有太多使用Entity Framework,但这似乎不正常。难道我做错了什么?有什么我可以看一下来加快这个速度吗?这个表很大,但是我读它的方式,这个代码应该只列举650个结果......这应该没有时间。

注意:不确定这是否相关,但是从所述表中选择所有行所需的时间大致相同(大约一分钟)

2 个答案:

答案 0 :(得分:0)

根据您最近的编辑,我知道发生了什么。我认为.GetResults()调用只是让查询准备好运行,利用延迟执行。只有当你在下一行中调用.ToList()时,它才真正走出去并试图自己构建实体(因此是时差)。

那么为什么要加载这么长时间呢?这可能有很多原因,包括:

  1. 您可能禁用了延迟加载。这将导致所有记录完全加载,并且具有所有相应的导航属性,并且DbContext跟踪所有这些记录。这使得内存消耗很多。您可能需要考虑启用它(但不是每个人都喜欢启用延迟加载)。

  2. 您允许跟踪器跟踪占用内存的所有记录。除此之外,如果您抓取的数据无论如何都是只读的,您可能需要考虑使用AsNoTracking,例如this blog post。这应该减少加载时间。

  3. 你可能会抓住很多专栏。我不知道你的程序返回了什么,但是如果它有很多行,有很多不同的列,所有这些数据被推入内存将花费很长的时间来处理。相反,您可能只想考虑根据需要选择尽可能少的列(通过在调用.Select()之前使用.ToList() )来获取您需要的内容。

答案 1 :(得分:0)

我的问题的解决方案是通过创建输入参数的副本来禁用参数嗅探。

alter procedure dbo.procedure
    @param int
as
begin
    set nocount on;

    declare @paramCopy int
    set @paramCopy = @param

    ...