Вопрос производительности между двумя запросами Linq в LinqPad и на практике

У меня есть запрос:

(from sr in ctx.STARS_Route
                            where sr.STARS_RouteStopDestination.Any(i => i.IsWorkingSet == true && i.STARS_DistrictRoute.DistrictId == districtId) == true
                            select sr.DistrictRouteNumber).Distinct();

В LinqPad запрос выполнялся примерно за 0,3 секунды. В таблице STARS_RouteStopDestination примерно 800 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 записей.

На практике метод, возвращающий результаты этого запроса, занимал 4+ секунды! Это не имело никакого смысла.

Единственное, о чем я мог подумать, это то, что предложение .Any занимало много времени, но LinqPad сказал, что запрос был быстрым. Я настроил тест (пожалуйста, простите имена):

using (STARSEntities ctx = new STARSEntities())
        {
            var Original = (from sr in ctx.STARS_Route
                            where sr.STARS_RouteStopDestination.Any(i => i.IsWorkingSet == true && i.STARS_DistrictRoute.DistrictId == districtId) == true
                            select sr.DistrictRouteNumber).Distinct();

            var Entity = (from rsd in ctx.STARS_RouteStopDestination
                          where rsd.STARS_DistrictRoute.DistrictId == districtId
                          && rsd.IsWorkingSet == true
                          select rsd.STARS_Route.DistrictRouteNumber).Distinct();

            DateTime startOriginal = DateTime.Now;
            routes = Original.ToList();
            Debug.WriteLine("Original took: " + (DateTime.Now - startOriginal).ToString());
            DateTime startEtity = DateTime.Now;
            routes = Entity.ToList();
            Debug.WriteLine("Entity took: " + (DateTime.Now - startEtity).ToString());
        }

Вывод поразил меня:
Оригинал занял: 00:00:04.0270000
Сущность заняла: 00:00:00.0200000

Почему запрос с предложением .Any выполняется намного дольше и почему LinqPad говорит, что исходный запрос выполняется немного быстрее, чем запрос Entity для того же набора данных?


person Noel    schedule 05.04.2011    source источник
comment
Что произойдет, если вы выполните запросы в обратном порядке?   -  person Ladislav Mrnka    schedule 05.04.2011
comment
Я предпочитаю использовать класс StopWatch в System.Diagnostics для измерения времени выполнения вместо DateTime.   -  person Diego Torres    schedule 05.04.2011
comment
Реверс: Сущность взяла: 00:00:00.0170000 Оригинал взяла: 00:00:04.0890000   -  person Noel    schedule 05.04.2011
comment
Я бы выполнил оба запроса и активировал SQL Profiler и посмотрел, как выглядят SQL-запросы, которые попадают на ваш SQL-сервер. Это может дать вам больше информации о разнице в производительности.   -  person Rus    schedule 05.04.2011
comment
Если вы используете LinqPad, вы сможете увидеть сгенерированный SQL. Может, это прольет свет. IIRC EF лучше генерирует SQL, чем L2S.   -  person DaveShaw    schedule 05.04.2011
comment
Используете ли вы в LINQPad автоматически сгенерированный DataContext (т. е. LINQ to SQL) или подключаетесь к своей модели Entity Framework?   -  person Joe Albahari    schedule 06.04.2011
comment
@Joe - я не подключаюсь к своей модели EF напрямую, а только к сгенерированной. Схема БД не изменилась с момента последнего обновления модели EF в моем проекте.   -  person Noel    schedule 07.04.2011
comment
Если вы используете сгенерированную модель LINQPad, вы используете LINQ to SQL, который создает другой (и обычно лучший) SQL, чем Entity Framework. В любом случае на вкладке преобразования SQL в LINQPad должно быть указано, какой SQL генерируется. Вы также можете подключиться к своей модели EF в LINQPad и сравнить.   -  person Joe Albahari    schedule 08.04.2011


Ответы (1)


Вы просто воздействуете на два разных объекта, у которых есть две разные стратегии получения результата. LINQPad создает модель LINQ to SQL и внедряет ваш код в метод с этой моделью в области действия.

Ваш класс STARSEntities относится к другому типу и, вероятно, имеет совершенно другое взаимодействие с базой данных.

LINQPad имеет собственное представление, отображающее выполняемый SQL. Вы должны сравнить его с SQL, выполняемым моделью EF. Это отображается в профилировщике SQL Server при выполнении.

person Tormod    schedule 31.07.2011