Казалось бы, простой запрос очень медленный в Entity Framework

Итак, у меня есть очень простая модель данных в моем проекте (нацеленная на .NET 4.0, с использованием EF 5, установленного NuGet, сначала база данных) с двумя таблицами, Item и ItemGroup.

Item-table имеет различные поля, как строковые, так и числовые, а также внешний ключ, указывающий на ItemGroup.

С другой стороны, ItemGroup имеет только идентификатор, имя и код (последние 2 из которых являются строками).

Теперь у меня примерно 50 тыс. элементов и только 100 групп элементов. Если я выполняю context.Items.ToList() с помощью SQL Profiler, продолжительность составляет около 2-3 секунд, что вполне приемлемо. Однако, если я хочу одновременно загрузить группы элементов с помощью context.Items.Include("ItemGroup").ToList(), время выполнения увеличивается примерно до 12 секунд. Кроме того, если я просто извлеку все группы элементов после извлечения всех элементов, время выполнения также будет очень большим. Это наводит меня на мысль, что именно сопоставление элементов с их соответствующими группами занимает время.

Однако это по-прежнему не объясняет, почему SQL Profiler сообщает, что очень простой запрос INNER JOIN занимает более 10 секунд, по сравнению с тем же самым запросом без JOIN, который занимает всего 2-3 секунды.

Я в растерянности, никогда раньше не сталкивался с такой проблемой, поэтому любые советы более чем приветствуются.


person bobblez    schedule 03.12.2012    source источник
comment
2-3 секунды на 100 строк? Для начала мне это кажется плохим, на каком оборудовании вы работаете?   -  person Justin Harvey    schedule 03.12.2012
comment
Если я сначала запрашиваю только группы, время сокращается до миллисекунд. Я предполагаю, что это сопоставление сущностей или что-то в этом роде, что требует времени.   -  person bobblez    schedule 03.12.2012
comment
Вы уверены, что внутреннее соединение выполняется для индексированных полей? Попробуйте использовать выходные данные профилировщика SQL в мастере настройки базы данных.   -  person devzero    schedule 03.12.2012
comment
Я проверил план выполнения в студии управления, и он предложил добавить индекс, что я и сделал. Но, похоже, это не имело никакого эффекта. Где я могу найти этот мастер настройки базы данных?   -  person bobblez    schedule 03.12.2012


Ответы (1)


В то время, когда вы используете активную загрузку (include), он загружает все дерево базы данных сразу из базы данных. Так что это очень медленно.

Но вы можете определить области, которые вам нужно улучшить, преобразовав запрос EF в T-SQL с помощью LinqPad, а затем с помощью консультанта по настройке ядра базы данных на Sql Server 2008 поможет вам определить индекс ключи, что вам нужно.

Microsoft также опубликовала статью о производительности EF вы можете прочитать.

person Sampath    schedule 03.12.2012
comment
Спасибо, хотя у меня уже есть T-sql запроса, и, как уже упоминалось, это всего лишь очень простой SELECT ‹это и это› FROM Items INNER JOIN ItemGroup - своего рода запрос, но SQL Profiler по-прежнему сообщает об указанных 12 секундах. как продолжительность. - person bobblez; 03.12.2012
comment
У вас есть соответствующий индекс для этого запроса, в соответствии с предложениями консультанта по настройке ядра базы данных? - person Sampath; 04.12.2012
comment
Да, я пытался запустить советник по настройке для запроса, но он не дал рекомендаций для новых индексов. - person bobblez; 04.12.2012
comment
Это означает, что вы создали необходимые индексы. Затем вам нужно проверить, является ли ваша медлительность только для первого запуска запроса. Если это так, вы можете получить более подробную информацию об этом, используя 2 ссылки, которые я упомянул выше в пункте 2 - Выполнение холодного или теплого запроса. .Проверьте и это. - person Sampath; 04.12.2012
comment
На самом деле простое добавление AsNoTracking() к моему запросу решило мои проблемы. Это, очевидно, требует ручного подключения, если я хочу зафиксировать изменения, внесенные в существующие объекты, но для моего варианта использования это работает хорошо. И решение можно найти в статье msdn, на которую вы ссылаетесь, я приму ваш ответ, спасибо. - person bobblez; 04.12.2012
comment
Рад слышать, что это помогло. - person Sampath; 09.09.2013