Entity Framework Generated SQL - SELECT TOP (X) занимает на 500% больше времени, чем SELECT - PullRequest
3 голосов
/ 26 января 2012

Я занимаюсь разработкой веб-сайта MVC, который использует Entity Framework.Я бывший человек из ADO.Net, поэтому для меня все это немного ново.В настоящее время мой EDM состоит из абстрактного объекта «Product», который имеет 5 различных объектов «type», которые наследуются от него.Объект «Продукт» сопоставляется с 7 или 8 таблицами и имеет около 50 свойств, каждый «тип», который наследуется от «Продукта», имеет от 5 до 20 дополнительных свойств, расширяющих «Продукт».Я заметил, что когда я использовал метод расширения .Take в IQueryable для возврата данных в сетку Telerik, возвращение данных занимало заметно больше времени, чем если бы я просто жадно возвращал всю коллекцию в память, используя .ToList.

Когда я запустил SQL Profiler, чтобы увидеть, что происходит, дьявол, вот что я нашел.

exec sp_executesql N'SELECT TOP (20)
[Project12].[C1] AS [C1], 
[Project12].[C2] AS [C2], 
[Project12].[C3] AS [C3], 
etc ... 508 SQL lines follow, too much to paste here unfortunately.

Для выполнения требуется 500 миллисекунд.Однако следующее:

exec sp_executesql N'SELECT
[Project12].[C1] AS [C1], 
[Project12].[C2] AS [C2], 
[Project12].[C3] AS [C3], 
etc ... 

Требуется около 80 миллисекунд для выполнения.

Итак, судя по приведенной выше логике, я должен отказаться от отложенного выполнения, и каждый раз, когда пользователь меняет страницу ...перенести весь набор данных в память (500 строк или около того).Кто-нибудь есть какие-либо предложения, что происходит и почему SQL Server 2005 ведет себя таким образом?

РЕДАКТИРОВАТЬ

Я поместил полный SQL на http://pastebin.com/rAGGSScA.Может ли быть так, что SQL кэширует «полный» выбор, а не кэширует результаты «TOP (20)»?

Статистика клиента для SELECT

Select

Статистика клиента для SELECT TOP (20)

Select Top

Ответы [ 2 ]

1 голос
/ 26 января 2012

Если они оба имеют ORDER BY, то я предполагаю, что медленный использует другой план, который менее эффективен, но выводит строки в желаемом порядке сортировки, а быстрый план использует другой план, который выводитстрок в несортированном порядке и имеет явный шаг SORT.

Может случиться, что при использовании более медленного плана SQL Server необходимо обработать более 20 строк, чтобы получить TOP 20 длявывод (так как многие из них исключаются объединениями или критериями предложения), и он не оценивает этот фактор правильно, что приводит к неправильной оценке медленного плана как более дешевого, чем быстрый.

1 голос
/ 26 января 2012

Где-то в ваших "508 строках SQL [которые] следуют" будет предложение ORDER BY.Вынуждая оценку «TOP (N)» для запроса, вы заставляете сервер оценивать этот заказ в соответствии с предложением намного раньше и вычислять все результатов (включая их порядок) перед любым может быть показано.Скорее всего, у вас будет совершенно другой план выполнения, и вы даже можете аннулировать индекс (или совпадать с менее желательным индексом).Без предложения «TOP (n)» сервер может начать показывать результаты, как только узнает, что будет использована запись.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...