3

我在通过 Web 应用程序运行的EF 查询和将 Profiler 生成的 T-SQL 直接运行到 SQL 查询窗口之间存在一些性能测量问题。

以下是我通过 Web 应用程序执行的 EF 查询:

IEnumerable<application> _entityList = context.applications
                    .Include(context.indb_generalInfo.EntitySet.Name)
                    .Include(context.setup_budget.EntitySet.Name)
                    .Include(context.setup_committee.EntitySet.Name)
                    .Include(context.setup_fund.EntitySet.Name)
                    .Include(context.setup_appStatus.EntitySet.Name)
                    .Include(context.appSancAdvices.EntitySet.Name)
                    .Where(e => e.indb_generalInfo != null);

                if (isIFL != null)
                    _entityList = _entityList.Where(e => e.app_isIFL == isIFL);

                int _entityCount = _entityList.Count(); // hits the database server at this line

在 SQL Profiler 中跟踪上述 EF 查询时,它显示执行大约需要 221'095 毫秒。(应用程序表有 30,000 多条记录,indb_generalInfo 有 11,000 多条记录,appSancAdvices 有 30,000 多条记录)。

但是,当我从 Profiler 复制 T-SQL 并直接从 Query 窗口运行它时,只需要大约4'000 毫秒

为什么会这样?

4

4 回答 4

6

这个查询中的毒液在第一个词中:IEnumerable<application>。如果您将其替换为var(ie IQueryable),则查询将被翻译成 SQL,直到并包括最后一个Count(). 这将花费更少的时间,因为传输的数据量几乎减少到零。

此外,正如 bobek 已经提到的,您不需要Includes ,因为您只是在计算context.applications项目。

除此之外,您总是会注意到使用像实体框架这样的 ORM 的开销。

于 2013-07-04T15:00:04.330 回答
0

那是因为 EF 需要首先将您的代码翻译成 TSQL,这也很昂贵。在此处查看此链接:http: //peterkellner.net/2009/05/06/linq-to-sql-slow-performance-compilequery-critical/它可以让您编译您的 LINQ,并且应该可以帮助您提高速度。另外,你真的需要这么多表来进行这个查询吗?也许你可以想办法把它过滤掉,只取出你需要的东西?

于 2013-07-04T14:36:38.560 回答
0

EF 在性能方面肯定是有代价的。但它也为复杂的 TSQL 提供了使用存储过程的灵活性。但在我看来,这应该是你最后的手段。

于 2013-07-04T14:57:35.580 回答
0

如果您对性能和 EF 感兴趣。 http://msdn.microsoft.com/en-us/data/hh949853.aspx

然而...

SQL Profiler 中的 EF Query 它显示执行大约需要 221'095 毫秒。

然后..

从 Profiler 复制 T-SQL 并直接从 Query 窗口运行

SQL 的来源无关紧要。Q1 花了 x 毫秒。基于 SQL 探查器信息完全相同的查询 Q1' 基于 SQL 探查器需要更少。这意味着SQL的来源不是问题,它意味着涉及环境问题。

最明显的解释是,SQL Server 缓冲了许多数据页,可以更好地服务于第二个相同的请求。

于 2013-07-04T15:08:50.667 回答