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 для тонкой настройки запросов в зависимости от производительности)
Спасибо