实体框架和SQL Server Profiler

时间:2013-07-04 14:25:22

标签: c# performance entity-framework sqlprofiler sql-server-profiler

我在通过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事件探查器中跟踪上述EF查询时,它显示执行时需要 221'095 ms 。 (应用程序表有30,000+,indb_generalInfo有11,000+,appSancAdvices有30,000多条记录)。

但是,当我从Profiler复制T-SQL并直接从查询窗口运行它时,它只需要 4'000 ms

为什么会这样?

4 个答案:

答案 0 :(得分:6)

此查询中的毒液首先出现在:IEnumerable<application>。如果您将其替换为var(即IQueryable),则查询将被转换为SQL,包括最后一个Count()。这将花费相当少的时间,因为传输的数据量几乎没有减少。

此外,正如bobek已经提到的那样,您不需要Include,因为您只计算context.applications个项目。

除此之外,您将始终注意到使用像Entity Framework这样的ORM的开销。

答案 1 :(得分:0)

这是因为EF需要先将您的代码转换为TSQL,这也是代价高昂的。在这里看一下这个链接:http://peterkellner.net/2009/05/06/linq-to-sql-slow-performance-compilequery-critical/它可以让你编译LINQ,并且可以帮助你提高速度。此外,您真的需要这个查询的许多表吗?也许你可以想出一种过滤掉它的方法,只提出你需要的东西?

答案 2 :(得分:0)

EF在性能方面肯定会有成本。但它也提供了将storageprocs用于复杂TSQL的灵活性。但在我看来,它应该是你的最后手段。

答案 3 :(得分:0)

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

...然而

  

SQL Profiler中的EF查询显示它花费了大约221'095毫秒   执行。

然后..

  

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

运行它

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

最明显的解释是,SQL服务器缓存了许多数据页,可以更好地为第二个相同的请求提供服务。