Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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. Need help optimize the below C# statement.

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);
like image 806
Kashif Khan Avatar asked Sep 18 '26 11:09

Kashif Khan


2 Answers

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. 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.

like image 89
Sampath Avatar answered Sep 20 '26 02:09

Sampath


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. 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;
like image 21
Wurd Avatar answered Sep 20 '26 01:09

Wurd



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!