简体   繁体   English

实体框架 .include 性能问题

[英]Entity Framework .include Performance Issue

I have the below query which is tremendously slow.我有以下查询非常慢。 I am new to Entity Framework and I believe it has got to do something with Eager Loading, Lazy Loading or Explicit Loading.我是 Entity Framework 的新手,我相信它必须对 Eager Loading、Lazy Loading 或 Explicit Loading 做一些事情。 Need help optimize the below C# statement.需要帮助优化以下 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);

You can improve the performance of many includes by creating 2 or more small data request from the database as shown below.According to my experience,you can give maximum 2 includes per query.More than that will give really bad performance.Yes,this is Ugly.您可以通过从数据库创建 2 个或更多小数据请求来提高许多包含的性能,如下所示。根据我的经验,您可以为每个查询提供最多 2 个包含。超过这个数量会产生非常糟糕的性能。是的,这是丑。 But it will give very good performance improvement.You too can try and feel that :)但它会带来非常好的性能提升。你也可以尝试感受一下:)

Note : This is just an example.注意:这只是一个例子。

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();

Above will bring small data set from database by using more than one traverse to the database.以上将通过多次遍历将数据库中的小数据集带到数据库中。

Another option is to use asynchronous loading of your collections if you don't need all your data up front.如果您不需要预先获取所有数据,另一种选择是使用集合的异步加载。

For example:例如:

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

You should also consider .AsNoTracking() if you don't plan on editing and saving the entities back to the db.如果您不打算编辑实体并将其保存回数据库,您还应该考虑.AsNoTracking() It gives a small performance boost but won't cache entities for future queries.它提供了小的性能提升,但不会为将来的查询缓存实体。

If you are going to explicitly handle all the collection loading eagerly or in code later on then use these too as they also give a small performance boost.如果您打算显式地处理所有的集合加载,或者稍后在代码中,那么也可以使用这些,因为它们也会带来小的性能提升。

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

Any Include() call translates to SQL join operator and the number of joins in your example is very serious.任何Include()调用都会转换为 SQL join运算符,并且示例中的连接数量非常严重。 If you really need to perform all the joins I'd optimize indexes by looking at the DB engine execution plan.如果您真的需要执行所有连接,我会通过查看数据库引擎执行计划来优化索引。

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

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