[英]Entity Framework - Performance in count
我对实体框架的性能有些疑问。
就像是
using (MyContext context = new MyContext())
{
Document DocObject = context.Document.Find(_id);
int GroupCount = context.Document.Where(w=>w.Group == DocObject.Group).ToList().Count();
}
在我的数据库中(大约3万个数据集)大约需要2秒钟,而这一个
using (MyContext context = new MyContext())
{
Document DocObject = context.Document.Find(_id);
int GroupCount = context.Document.Where(w=>w.Group == DocObject.Group).Count();
}
需要0.02秒。
当我的10个文档过滤器需要等待20秒时,我检查了代码,并将其更改为在Count()
之前不使用ToList()
Count()
。
有什么主意为什么要用ToList()
这行需要2秒?
调用ToList()
然后再调用Count()
将:
SELECT FROM WHERE
List<T>
对象 Count
属性的结果 针对IQueryable
调用Count()
将:
SELECT COUNT FROM WHERE
Int32
显然,如果您只对项目的数量感兴趣( 而不对项目本身感兴趣),则永远不要首先调用ToList()
,因为它不需要很多资源。
是的,如果不使用ToList()
,则不会从数据库中检索对象,因此ToList()
将评估结果(从数据库中检索对象)。
Linq-To-Entities默认情况下使用LazyLoading。
它的工作原理是这样的; 当您使用Linq-To-Entities查询基础数据库连接时,您将获得一个代理对象,可以在该对象上执行许多操作(计数为1)。 这意味着您不会立即从数据库中获取所有数据,而是在评估时从数据库中检索了对象。 评估对象的一种方法是使用ToList()。
也许你应该读这篇 。
因为ToList()
将查询整个对象的数据库(会做一个SELECT *
这么说的),然后你会使用Count()
在内存中的列表上的所有记录,而如果你使用Count()
上IQueryable
(不在List
),EF会将其转换为简单的SELECT COUNT(*)
SQL查询
您的第一个查询未完全转换为sql-调用.ToList().Count()
,您基本上是在说“全部下载,将其具体化为POCO并调用名为Count()
扩展方法”,这当然需要一些时间。
但是,您的第二个查询已转换为类似于select count(*) from Documents where GroupId = @DocObjectGroup
,执行起来要快得多,并且您无法实现任何东西,只是简单的标量。
使用扩展方法Enumerable.ToList()
将从IEnumerable<T>
源集合构造一个新的List对象,这意味着执行ToList()
会产生相关的成本。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.