Я изучаю проблему с производительностью с использованием Entity Framework v6 за последние дни и не вижу способа решить проблему.Производительность Entity Framework с использованием другого типа доступа
У меня есть объект A (называемый компанией в приведенных ниже примерах), который содержит список вторых объектов B (материал в приведенных ниже примерах). Теперь я хочу захватить один кусок A и работать со всеми объектами типа B, которые содержатся в A. Для этого теста я использую 10000 штук B.
Когда я получаю объект, время отклика с сервера 5-10 секунд, используя один тип доступа, используя второй тип доступа, он использует только 0,2-0,3 секунды. Я просто не могу понять, почему.
Быстрая реакция (~ 0,2 до 0.3с): 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
}
Медленная реакция (~ 5 - 10 секунд): Пример 2.
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
}
Существует вторая возможность для меня, чтобы замедлить реакция: ПРИМЕР3
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
}
Я просто не могу решить проблему. Я использовал проблеск, чтобы посмотреть график. Проблема заключается в следующем: в первых двух примерах время выполнения SQL составляет всего ~ 100 мс. В примере 2 существует промежуток времени между последним исполнением SQL и конечным запросом в 5-10 секунд. В примере 3 оператор SQL совершенно другой (и сложный) и фактически занимает 5-10 секунд. Операторы SQL для примеров 1 и 2 точно такие же!
Есть ли у кого-нибудь идеи, что происходит?
Эти определения моих двух классов:
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()
{
}
}
Вы уверены, что пример 1 и 2 производят Точно такой же запрос? Я считаю, что пример 1 имеет дополнительное место. Я считаю, что это быстрее, поскольку вы используете инструкцию Where для первичного ключа, который, скорее всего, является индексом - это может вызвать скорость example1 – MajkeloDev
. Второй пример дает больше записей, поэтому, скорее всего, это не sql enginge slow, чтобы сделать этот запрос, это просто больше данные для отправки. – MajkeloDev
На примерах 1 и 2 действительно два оператора SQL: сначала получен класс компании. После этого будут получены материалы. Оба оператора SQL точно одинаковы для примеров 1 и 2 (за исключением некоторых комментариев). –