实体框架和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毫秒。
为什么会这样?
此查询中的毒液在第一个单词中: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缓冲了许多数据页,可以更好地为第二个相同的请求提供服务。