EF Core Lazy加载非常慢

时间:2018-11-03 14:18:39

标签: c# ef-core-2.1

我做了一个小测试,启用了懒惰的Model.Item2

(使用EF Core 2.1.4)

我遍历有无仪器,这就是我得到的结果

案例1

loading.optionsBuilder.UseLazyLoadingProxies().UseSqlServer(ConnectionString);

案例2

var instruments = db.instruments.OrderBy(t=>t.id).Include(t=>t.NavPro1).ThenInclude(t=>t.NavPro2).Take(200);

然后

var instruments = db.instruments.OrderBy(t=>t.id).Include(t=>t.NavPro1).ThenInclude(t=>t.NavPro2).Take(200);

花7s即可获得10万行,而不会延迟加载

需要160 s才能获得3k行的延迟加载。

如何获得良好的性能?

3 个答案:

答案 0 :(得分:3)

是,请避免延迟加载。期间。

问题是-总是追溯到曾经构建的每个ORM-如果您进行延迟加载,则每个引用都是延迟加载。往返1次以上(每个住宿至少一次)。分开的SQL执行,分开的网络时间。这加起来非常快。

这就是为什么以前编写的每个ORM通过.include语句在EF变体中都支持NON延迟加载的原因,该语句扩展了SQL或生成了单独的SQL(ef核心,列出以实现与有效sql的关系)。

如果您坚持使用延迟加载-就像您的问题所暗示的那样,您不会在代码上散布任何魔法尘,从而避免了延迟加载的隐含负面影响。

现在,补充一点-3.0之前的任何EF Core都已损坏。是的,那是3.0-甚至是2.2。看到,各个部分都有很多问题,包括基本的LINQ。和性能。至少2.2(希望在一个月内出现)应该可以解决一些问题。在此之前,请尝试使用.include和AsNoTracking-因为IIRC存在一个性能错误,在加载20万行时也会遇到问题。

答案 1 :(得分:2)

这是一个普遍的问题,称为N + 1问题。

这里发生的是,当您使用延迟加载时,您会有更多的请求。

在使用Include的情况下,您有一个巨大的请求可以提供所有数据-或每个表一个请求,因此您的情况下为三个请求。这取决于您的数据的确切结构。

在延迟加载的情况下,您对仪器有一个请求,而对于每种仪器,则有另一个对NavPro1的请求。对于每个NavPro1元素,您还需要另一个NavPro2。

因此,如果您有1000台仪器,每台仪器有10台NavPro1,则现在您有1 +(1000 *(1 + 10))= 11001个请求,而不是最多三个请求。那太慢了,期间。

答案 2 :(得分:-1)

https://github.com/aspnet/EntityFrameworkCore/issues/12451

这是解决方案

服务     .AddDbContext(b => b.ReplaceService());