本文介绍了为什么实体框架生成的查询需要两倍的时间才能运行,直到相同的查询运行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我有一个简单的EF实现,其中我检索〜20K个记录,并包含两个子实体: using(InsightEntities context = new InsightEntities()) { return context.Accounts .Include(x => x.Division) .Include(x => x.Division.Company ) .OrderBy(x => x.ID) .AsNoTracking() .ToList(); } 当我通过SQL Profiler配置EF调用时,SQL命令的持续时间是〜1.2s,即使在后续的电话。但是,如果我复制和粘贴EF生成的相同的SQL,并通过SSMS直接运行它,持续时间是一半。 以下是EF呼叫(红色椭圆)和直接呼叫(绿色椭圆形)的屏幕截图: 我明白,大量的工作将数据映射到对象,解释关系等等,但是为什么单独的查询需要两倍的时间才能直接运行相同的查询?是否有可能优化查询的默认EF连接字符串的更改? (我应该补充说,查询本身是完全优化所有外键的索引。) 谢谢!解决方案两者之间的读数是一样的跟踪,所以它看起来没有计划相关。 很可能只是因为实体框架在消耗结果集时所花的时间更长。例如创建以下标量UDF CREATE FUNCTION dbo。 GetTime() RETURNS CHAR(12) AS BEGIN 返回转换(VARCHAR(12),GETDATE(),114) END 然后在Management Studio中运行 SELECT TOP(10)CAST(dbo.GetTime()AS CHAR(8000)) FROM sys.all_objects 几乎立即完成,但模拟一个更多工作的客户端。 using(SqlConnection con = new SqlConnection (connectionString)) { con.Open(); using(SqlCommand command = new SqlCommand( @SELECT TOP(10)CAST(dbo.GetTime()AS CHAR(8000)) FROM sys.all_objects con)) { using(SqlDataReader reader = command.ExecuteReader()) { while(reader.Read()) {控制台.WriteLine(reader.GetString(0).TrimEnd()); System.Threading.Thread.Sleep(1000); } } } } 在Profiler中持续8秒。 上面显示的结果是 23:55:54:870 23:55:54:870 23:55:54:870 23:55:55:870 23:55:56:870 23:55:57: 870 23:55:58:870 23:55:59:870 23:56:00:870 23:56:01:870 第一行和最后一行之间的时间戳差异为7秒。在继续执行SQL Server延迟等待客户端(等待类型 ASYNC_NETWORK_IO )之前,前三行几乎立即返回, I have a simple EF implementation in which I retrieve ~20K records and include two child entities: using (InsightEntities context = new InsightEntities()){ return context.Accounts .Include(x => x.Division) .Include(x => x.Division.Company) .OrderBy(x => x.ID) .AsNoTracking() .ToList();}When I profile the EF call via SQL Profiler, the duration of the SQL command is ~1.2s, even on subsequent calls. But if I copy and paste the same SQL that EF is generating and run it directly through SSMS, the duration is half that.Below is a screenshot of EF calls (red ovals) and direct calls (green ovals):I understand that EF does a lot of work mapping data to objects, interpreting relationships, and so on, but why would the query alone take twice as long as the same query run directly? Are there changes to the default EF connection string that might optimize the queries?(I should add that the query itself is completely optimized with indices for all foreign keys.)Thank you! 解决方案 The reads are the same between the two traces so it doesn't look plan related.Quite likely it is just because Entity Framework does more when it consumes the result set so takes longer.For example creating the following scalar UDFCREATE FUNCTION dbo.GetTime()RETURNS CHAR(12)AS BEGIN RETURN CONVERT(VARCHAR(12), GETDATE(), 114) ENDThen running in Management StudioSELECT TOP (10) CAST(dbo.GetTime() AS CHAR(8000))FROM sys.all_objectsCompletes almost instantly but simulating a client that does more workusing (SqlConnection con = new SqlConnection(connectionString)){ con.Open(); using (SqlCommand command = new SqlCommand( @"SELECT TOP (10) CAST(dbo.GetTime() AS CHAR(8000)) FROM sys.all_objects", con)) { using (SqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { Console.WriteLine(reader.GetString(0).TrimEnd()); System.Threading.Thread.Sleep(1000); } } }}Shows up in Profiler as duration 8 seconds.The results of the run shown above are 23:55:54:87023:55:54:87023:55:54:87023:55:55:87023:55:56:87023:55:57:87023:55:58:87023:55:59:87023:56:00:87023:56:01:870The difference in time stamps between 1st and last row are 7 seconds. The first three rows were returned almost immediately and there after SQL Server was delayed waiting on the client (with wait type ASYNC_NETWORK_IO) before continuing with execution. 这篇关于为什么实体框架生成的查询需要两倍的时间才能运行,直到相同的查询运行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云! 08-26 08:33