实体框架v6.1查询编译性能

时间:2016-07-28 07:32:43

标签: c# sql-server entity-framework linq linqpad

我很困惑如何编译和执行EF LINQ查询。当我在LINQPad中运行一段程序时,我得到了不同的性能结果(每次相同的查询需要不同的时间)。请在下面找到我的测试执行环境。

使用的工具:EF v6.1& LINQPad v5.08。 参考数据库:从MSDN下载的ContosoUniversity DB。

对于查询,我正在使用人员,课程和来自上述DB的Departments表;见下文。

enter image description here

现在,我有以下数据:

enter image description here

查询目标:获取第二人称及相关部门。 查询:

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根据性能微调查询)

由于

0 个答案:

没有答案