繁体   English   中英

实体框架 .include 性能问题

[英]Entity Framework .include Performance Issue

我有以下查询非常慢。 我是 Entity Framework 的新手,我相信它必须对 Eager Loading、Lazy Loading 或 Explicit Loading 做一些事情。 需要帮助优化以下 C# 语句。

var queryResult = CurrentSession.Set<SomeType_T>().Include(a => a.SomeType1_T)
                                .Include(a => a.SomeType1_T.Catalog_Type_T)
                                .Include(a => a.SomeType1_T.SomeType4_T)
                                .Include(a => a.SomeType1_T.SomeType2_T)
                                .Include("SomeType1_T.SomeType2_T.SomeType3_T")
                                .Include(a => a.SomeType1_T.SomeType4_T.SomeType5_T)
                                .Include(a => a.SomeType1_T.SomeType5_T)
                                .Include(a => a.SomeType1_T.Questions_T)
                                .Include(a => a.SomeType1_T.Questions_T.Question_Type_T)
                                .Include(a => a.SomeType1_T.Members_T)
                                .Include(b => b.SomeMasterType_T)
                                .Include(b => b.SomeMasterType_T.SomeMasterType1_T)
                                .Include(c => c.SomeType6_T)
                                .Include(d => d.SomeType7_T)
                                .Include(d => d.SomeType8_T)
                                .Include(d => d.SomeType8_T1)
                                .Where(t => t.SomeType9_T == _MatchThisKey);

您可以通过从数据库创建 2 个或更多小数据请求来提高许多包含的性能,如下所示。根据我的经验,您可以为每个查询提供最多 2 个包含。超过这个数量会产生非常糟糕的性能。是的,这是丑。 但它会带来非常好的性能提升。你也可以尝试感受一下:)

注意:这只是一个例子。

var userData = from u in db.Users
                        .Include(p=>p.UserSkills)
                        .Include(p=>p.UserIdeas)
                        .FirstOrDefault();

 userData = from u in db.Users
                    .Include(p=>p.UserFriends)
                    .Include(p=>p.UserFriends1)
                    .FirstOrDefault();

以上将通过多次遍历将数据库中的小数据集带到数据库中。

如果您不需要预先获取所有数据,另一种选择是使用集合的异步加载。

例如:

var initialResult = db.Person.Include(c=>c.FirstCollection).First();
var load1 = db.Entry(initialResult).Collection(c=>c.SecondCollection).LoadAsync();    
//do all the work you can
await load1;
//continue with more work

如果您不打算编辑实体并将其保存回数据库,您还应该考虑.AsNoTracking() 它提供了小的性能提升,但不会为将来的查询缓存实体。

如果您打算显式地处理所有的集合加载,或者稍后在代码中,那么也可以使用这些,因为它们也会带来小的性能提升。

db.Configuration.LazyLoadingEnabled = false;
db.Configuration.ProxyCreationEnabled = false;

任何Include()调用都会转换为 SQL join运算符,并且示例中的连接数量非常严重。 如果您真的需要执行所有连接,我会通过查看数据库引擎执行计划来优化索引。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM