我一直在玩制作我自己的实体框架(针对个人项目,并出于对这样的事情的好奇心)。
当我使用包含700k行和5列(名为MassData
)的数据表进行实体框架性能测试时,我遇到了一些特殊问题,我希望有人可以向我解释。< / p>
运行以下测试:
var Context = new EntityFameworkContext();
var first = Context.MassData.Where(x => x.Id == 1);
var firstFifty = Context.MassData.Where(x => x.Id < 50).ToArray();
上下文创建需要35毫秒,获得first
需要大约215毫秒,获得firstFifty
需要14毫秒。
删除'first'
,获取'firstFifty'
大约需要210毫秒。
如果我将'first'
查询切换为选择所有内容的Where()
(仍然没有迭代),结果是一样的。
我的第一个想法是,这是在DbSet
中加载延迟数据的一些情况,第一个查询枚举下一个访问的数据(即使第一个查询没有迭代任何东西) )。这可以解释为什么第一个总是需要至少200毫秒而不管查询,而第二个运行速度就像没有涉及数据库连接一样快(&#39; firstFifty&#39;需要最少25毫秒才能运行SQL查询,超过我在这里看到的15ms)。
除了加载所有MassData
需要5秒钟。只需阅读它大约需要2.5。因此它无法加载所有内容,但它显然加载的内容超过了第一个查询所需的内容。很明显,我错过了一些东西。
有人会碰巧解释为什么
var first = Context.MassData.Where(x => x.Id == 1);
查询加快了
var firstFifty = Context.MassData.Where(x => x.Id < 50).ToArray();
查询?
修改
原来,它实际上与延迟加载毫无关系。第一个查询打开连接并且(我假设)执行并将实体类型的验证存储在数据库表中。然后第二个查询不必打开连接,或者如果有任何验证就做了很多,在这种情况下,第二个查询的持续时间匹配,一切都有意义。
编辑2:
修改后的标题可以更好地匹配问题的最终结果(延迟加载工作如何=&gt;实体加载如何工作)。
答案 0 :(得分:0)
因为您仍然在加载实体类型及其先决条件。无论您尝试查询什么。 EF的Lambda表达式仍然是SQL,从Lambda到String子句和语句的转换。所以第一个缓慢不是来自Query,而是来自EF Initial设置。
请记住,您仍然在创建EF的实例,因此会占用一些运行时进程。然后剩下的就是查询提取时间。由于CLR过程,这是不可避免的过程。
所以,一般来说。第二个查询已准备好进行查询,因为在您的模型中,您设置的EF仍在使用中,但是当垃圾收集决定它不会在任何地方使用时,那么您对下一个会话的查询将会变慢EF的开始初始化。 &#34;关于你与DB的连接仍然是开放的&#34;就这么简单。
答案 1 :(得分:0)
有一些工具可以显示sql server活动,因此您不必猜测(例如,用于microsoft sql server的sql profiler)。但是第一次查询的延迟可能与数据库无关,它只是EF内部初始化。 EF众所周知是懒惰的。