I have been looking into an issue with performance using Entity Framework v6 for the last days and see no way to resolve the issue.
I have an object A (called Company in the examples below) which contains a list of second objects B (Material in the examples below). I now want to grab one piece of A and work with all objects of type B which are contained in A. For this test I am using 10000 pieces of B.
When I receive the object the response time from the server is 5-10 seconds using one type of access, using the second type of access it is using only 0.2 to 0.3 seconds. I am just not able to figure out why.
Fast reaction (~ 0.2 to 0.3s): EXAMPLE1
using (var cont = new Context())
{
Company C = cont.Companies.SingleOrDefault(o => o.ID == 18);
var mat = cont.Materials.Where(o => o.Company.ID == 18);
foreach (Material m in mat) { } // do stuff, does not matter
}
Slow reaction (~ 5 - 10s): EXAMPLE2
using (var cont = new Context())
{
Company C = cont.Companies.SingleOrDefault(o => o.ID == 18);
var mat = C.materials; // takes forever
foreach (Material m in mat) { } // do stuff, does not matter
}
There is a second possibility for me to get to slow reaction: EXAMPLE3
using (var cont = new Context())
{
cont.Configuration.LazyLoadingEnabled = false;
Company C = cont.Companies.Include(o => o.materials).SingleOrDefault(o => o.ID == 18); // takes forever
var mat = C.materials; // fast
foreach (Material m in mat) { } // do stuff, does not matter
}
I am just not able to figure out the problem. I have used glimpse to look at the timeline. Problem is: in the first two examples the SQL execution time is only ~100 ms. In Example 2 there is a time-gap between last execution of SQL and end-request of 5 - 10 seconds. In example 3 the SQL statement is completely different (and complex) and actually takes 5 - 10 seconds. The SQL statements for examples 1 and 2 are exactly the same!
Does anybody have an idea what is going on?
These are the definitions of my two classes:
public class Company
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
public virtual List<Material> Materials { get; set; }
public Company()
{
}
}
public class Material
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
public string Producer { get; set; }
[Required]
public virtual Company Company { get; set; }
public Material()
{
}
}
After more testing I found a solution to make all queries equally fast. The Material class needs a direct reference to the index of the Company class. I assume access is much faster this way, because the object does not have to be loaded every time?! I still don't understand why the first example was fast with the original classes. Or why the SQL queries look exactly the same in examples 1 and 2 with a significant performance difference.
public class Material
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
public string Producer { get; set; }
[Required]
public int CompanyId { get; set; } // THIS IS NEW!!!
public virtual Company Company { get; set; }
public Material()
{
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With