实体框架和SQL Server Profiler

本文关键字:Server Profiler SQL 框架 实体 | 更新日期: 2023-09-27 18:20:57

我在通过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'095ms。(应用程序表具有30000+条记录,indb_generalInfo具有11000+条记录,appSancAdvices具有30000+个记录)。

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

为什么会这样?

实体框架和SQL Server Profiler

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

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

除此之外,您还会注意到使用类似ORM的实体框架的开销。

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

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

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

然而。。。

SQL Profiler中的EF查询显示处决

那么。。

从Profiler复制T-SQL,并直接从查询窗口运行

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

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