Мы начали переносить проект из VS2008 с хранимыми процедурами в VS2010 с Entity Framework 4 как ORM.
Теперь мне пришлось выполнить довольно сложный запрос LINQ, чтобы вытащить данные из нашей базы данных.Обычно я сначала пытаюсь выяснить запрос LINQ, используя LINQPad (отличный инструмент!).
Теперь я заметил, что SQL, созданный LINQ to Entities, ужасен по сравнению с LINQ toSQL, который выдает оператор SQL, аналогичный тому, который мы делали ранее с хранимой процедурой.В запросе L2E было так много вложенных SELECT и INNER JOINS, что мне было просто больно смотреть на него!
Мне было любопытно, я выбрал еще один довольно сложный запрос LINQ и сравнил сгенерированный SQL LINQ to Entites с LINQ.SQL генерируется SQL.Результат был аналогичным, L2E SQL был ужасен и, скорее всего, крайне неэффективен (я не тестировал его, но мне это ясно, глядя на оператор SQL)
Извините, что могуВ данный момент я не могу привести несколько примеров запросов, но если интерес достаточно высок, я могу создать фиктивную базу данных и создать запросы, аналогичные тем, которые мы используем (запутывание наших запросов и таблиц сделает запросы нечитаемыми и бессмысленными)
Итак, каков ваш опыт работы с Entity Framework?Никто не заметил ужасных операторов SQL или большинство людей просто не заботятся?Я упускаю что-то фундаментальное в L2E, что мне следует знать?
Сейчас я очень сожалею, что мы выбрали Entity Framework вместо LINQ to SQL.
Редактировать:
Итак, я сделал несколько тестов и WOW, я удивлен!Я поместил сгенерированные операторы SQL в окно запроса в SQL Server Management Studio и выполнил каждый запрос несколько раз.Вот средние результаты выполнения запроса в цикле WHILE 1, 10 и 100 раз.
1 time:
LINQ to SQL: 440ms
LINQ to Entities: 240ms
10 times:
LINQ to SQL: 2900ms
LINQ to Entities: 910ms
100 times:
LINQ to SQL: 31600ms
LINQ to Entities: 7000ms
Я действительно удивлен!
Моим следующим тестом было создание простой программы на C # длясоздать и выполнить инструкцию SQL.Я использовал LINQpad для удобства.Для каждого теста я использовал LINQ to SQL и поставщика данных LINQ to Entities в LINQPad.Запрос в точности один и тот же каждый раз.Тестовая программа выглядит следующим образом:
void Main()
{
var sw = new Stopwatch();
for(int i = 0; i < 5; i++)
{
sw.Start();
for(int y = 0; y < 10; y++)
{
ExecuteQuery();
}
sw.Stop();
Console.WriteLine(string.Format("Pass {0}: {1}", i, sw.ElapsedMilliseconds));
sw.Reset();
}
}
private void ExecuteQuery()
{
//here is my 'complex' linq query
var dummy = (from p in....).ToList();
}
На этот раз я немного разочарован, результаты таковы:
LINQ to SQL:
Run 0: 805
Run 1: 726
Run 2: 722
Run 3: 717
Run 4: 767
LINQ to Entities:
Run 0: 3031
Run 1: 3231
Run 2: 3085
Run 3: 3127
Run 4: 3148
Полагаю, разница связана с оператором SQLпоколение?Или я бенчмаркинг совершенно не так?Предложения?
Edit2: Я реализовал запрос LINQ в нашем проекте (забыл упомянуть, что проект является веб-приложением ASP.NET MVC 3 RC).Мы в основном отображаем страницу с заказной сеткой.Загрузка данных для сетки с помощью LINQ to Entities занимает около 300-400 мс!Загрузка данных с помощью LINQ to SQL занимает около 70-80 мс.На самом деле это очень похоже на мои результаты в моем тестовом приложении в LINQPad выше.
Я искал проблемы с производительностью в EF в течение последних нескольких часов и обнаружил множество проблем с начальными запросами.И действительно, начальный запрос медленнее, но всего около 200 мс, поэтому первый запрос занимает около 600 мс, а каждый последующий запрос - 300–400 мс.Я также читал о прекомпиляции представлений с EdmGen , но это не имело значения.Я нашел еще одно сообщение в блоге , в котором сравнивалась производительность LINQ to SQL с EF , и результат, похоже, был аналогичным, хотя это было для EF 3.5.Затем я нашел в блоге сообщение об EF с тяжелым наследованием , но это не относится к моему случаю.
Кроме сотни сообщений типа "первоначальный запрос идет медленно", которые я не делалне найти ничего, связанного с моей проблемой.Я имею в виду, я не возражаю против снижения производительности по сравнению с Linq для SQL, но 70мс против 300мс - огромная разница!Это влияет на взаимодействие с пользователем нашего веб-приложения.
Последнее, что я собираюсь попробовать, - это предварительно скомпилировать запрос.Если производительность не улучшается, я окончательно переключаюсь на LINQ to SQL (хотя сам генерируемый SQL действительно быстрее!)