Entity Framework v6.1 производительность компиляции запросов

Я запутался, как запросы EF LINQ компилируются и выполняются. Когда я запускаю часть программы в LINQPad пару раз, я получаю разные результаты производительности (каждый раз, когда один и тот же запрос занимает разное количество времени). Пожалуйста, найдите ниже мою среду выполнения теста.

используемые инструменты: EF v6.1 и LINQPad v5.08. Ссылка DB: ContosoUniversity DB, загруженная из MSDN.

Для запросов я использую таблицы Persons, Courses & Departments из вышеуказанной БД; увидеть ниже.

Теперь у меня есть данные ниже:

Цель запроса: получить второго человека и связанные с ним отделы. Запрос:

var test = (
    from p in Persons
    join d in Departments on p.ID equals d.InstructorID 
    select new {
       person = p,
       dept = d
    }
);

var result = (from pd in test
    group pd by pd.person.ID into grp
    orderby grp.Key 
    select new {
          ID = grp.Key,
          FirstName = grp.First().person.FirstName,
          Deps = grp.Where(x => x.dept != null).Select(x => x.dept).Distinct().ToList()
         }).Skip(1).Take(1).ToList();

   foreach(var r in result)
   {
        Console.WriteLine("person is..." + r.FirstName);
        Console.WriteLine(r.FirstName + "' deps are...");
        foreach(var d in r.Deps){
           Console.WriteLine(d.Name);
        }
   }

Когда я запускаю это, я получаю результат, и LINQPad отображает значение, полученное во время, от 3,515 с до 0,004 с (в зависимости от того, сколько разрыва я принимаю между различными прогонами).

Если я возьму сгенерированный SQL-запрос и выполню его, этот запрос всегда будет выполняться в диапазоне от 0,015 с до 0,001 с.

Сгенерированный запрос:

-- Region Parameters
DECLARE @p0 Int = 1
DECLARE @p1 Int = 1
-- EndRegion
SELECT [t7].[ID], [t7].[value] AS [FirstName]
FROM (
   SELECT ROW_NUMBER() OVER (ORDER BY [t6].[ID]) AS [ROW_NUMBER], [t6].[ID],   [t6].[value]
     FROM (
       SELECT [t2].[ID], (
         SELECT [t5].[FirstName]
          FROM (
            SELECT TOP (1) [t3].[FirstName]
            FROM [Person] AS [t3]
            INNER JOIN [Department] AS [t4] ON ([t3].[ID]) = [t4].    [InstructorID]
            WHERE [t2].[ID] = [t3].[ID]
            ) AS [t5]
        ) AS [value]
    FROM (
        SELECT [t0].[ID]
        FROM [Person] AS [t0]
        INNER JOIN [Department] AS [t1] ON ([t0].[ID]) = [t1].[InstructorID]
        GROUP BY [t0].[ID]
        ) AS [t2]
      ) AS [t6]
  ) AS [t7]
WHERE [t7].[ROW_NUMBER] BETWEEN @p0 + 1 AND @p0 + @p1
ORDER BY [t7].[ROW_NUMBER]
GO

-- Region Parameters
DECLARE @x1 Int = 2
-- EndRegion
SELECT DISTINCT [t1].[DepartmentID], [t1].[Name], [t1].[Budget], [t1].    [StartDate], [t1].[InstructorID], [t1].[RowVersion]
FROM [Person] AS [t0]
INNER JOIN [Department] AS [t1] ON ([t0].[ID]) = [t1].[InstructorID]
WHERE @x1 = [t0].[ID]

Мои вопросы: 1) Верны ли эти утверждения LINQ? Или они могут быть оптимизированы? 2) Нормальная ли разница во времени для выполнения запроса LINQ?

Другой другой вопрос: я изменил первый запрос для немедленного выполнения (называется ToList перед вторым запросом). На этот раз сгенерированный SQL очень прост, как показано ниже (не похоже, что существует SQL-запрос для первого оператора LINQ с включенным ToList()):

 SELECT [t0].[ID], [t0].[LastName], [t0].[FirstName], [t0].[HireDate], [t0].      [EnrollmentDate], [t0].[Discriminator], [t1].[DepartmentID], [t1].[Name], [t1].   [Budget], [t1].[StartDate], [t1].[InstructorID], [t1].[RowVersion]
 FROM [Person] AS [t0]
 INNER JOIN [Department] AS [t1] ON ([t0].[ID]) = [t1].[InstructorID]

Выполнение этого измененного запроса также занимало различное количество времени, но разница не так велика, как при первом запуске набора запросов.

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

Пожалуйста, руководство. (Примечание: я немного разбираюсь в SQL Server, поэтому я использую LINQPad для тонкой настройки запросов в зависимости от производительности)

Спасибо

0 ответов

Другие вопросы по тегам