我很困惑如何编译和执行EF LINQ查询。当我在LINQPad中运行一段程序时,我得到了不同的性能结果(每次相同的查询需要不同的时间)。请在下面找到我的测试执行环境。
使用的工具:EF v6.1& LINQPad v5.08。 参考数据库:从MSDN下载的ContosoUniversity DB。
对于查询,我正在使用人员,课程和来自上述DB的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非常简单,如下所示(它看起来不像包含ToList()的第一个LINQ语句的SQL查询一样):
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根据性能微调查询)
由于