我有一个从Entity Framework生成的简单查询,在.NET应用程序中完成大约需要55秒。当我在SSMS中使用相同的参数运行查询时,它在大约4秒内运行。
我知道不同的设置选项可以生成不同的查询计划。我使用Profiler来显示“Showplan XML Statistics Profile”,我可以验证查询计划是否相同,但是Profiler仍会显示非常不同的持续时间,具体取决于查询是否从应用程序运行。慢速运行查询的持续时间约为50秒。
我还使用DMV显示sys.dm_exec_query_stats中的execution_count,以验证在两种情况下都使用了相同的查询计划。
查询本身非常简单,但它返回了近100.000条记录。如果我将查询重写为存储过程,它在应用程序和SSMS中都可以快速运行,但仍然使用相同的简单执行计划。
我想了解导致此行为的原因。
-----------更新----------------------------------- -------
我一直认为这是一个Sql Server问题,但我开始怀疑这可能是一个应用程序问题。
应用程序对使用ICollection声明的导航属性使用Count。
public class Department
{
public int DepartmentID { get; set; }
...
public virtual ICollection<Course> Courses { get; set; }
}
and then in the application
var department = getDepartmentById(departmentId);
Assert.IsTrue(department.Courses.Count() > 100000);
在应用程序中,因为Courses是使用ICollection声明的,所以使用Linq-to-Object而不是LINQ-to-SQL。这意味着将获取所有行并在内存中计算课程。
应用程序是否可能导致性能下降。它以这样的方式获取行,实际上SQL Server必须等待应用程序完成。
这实际上解释了很多。
示例不显示实际的类或实际的Linq,但它们显示相同的行为。