2014-02-20 30 views
1

我有它运行得非常慢(我看到3秒次)Linq的语句运行很慢

var results = 
    from pi in ProductItems.Include("Parent") 
    join nt in PicklistDetails 
     on pi.Diameter.PicklistCode + "-" + pi.Schedule.PicklistCode 
     equals nt.PicklistCode 
    where pi.Active 
    select new 
    { 
     Active = pi.Active, 
     ID = pi.ID, 
     IsCategory = pi.IsCategory, 
     Name = pi.Name, 
     Diameter = pi.Diameter.Value1, 
     Thickness = nt.Value1, 
     ThicknessCode = pi.Diameter.PicklistCode + "-" + pi.Schedule.PicklistCode 
    };  
results.Dump(); 

我可以直接在SQL编写的等效声明,它运行得更快以下LINQ语句。有人能告诉我是否有更有效的方法来编写linq查询吗?

更新:感谢所有迄今为止的答复这里是一些更多的信息。从上面的LINQ查询生成的SQL出来,像这样:

SELECT 
[Extent1].[ID] AS [ID], 
[Extent1].[Active] AS [Active], 
[Extent1].[IsCategory] AS [IsCategory], 
[Extent1].[Name] AS [Name], 
[Extent7].[Value1] AS [Value1], 
[Extent2].[Value1] AS [Value11], 
[Extent7].[PicklistCode] + N'-' + [Extent8].[PicklistCode] AS [C1] 
FROM [dbo].[ProductItem] AS [Extent1] 
INNER JOIN [dbo].[PicklistDetails] AS [Extent2] ON EXISTS (SELECT 
    1 AS [C1] 
    FROM  (SELECT 1 AS X) AS [SingleRowTable1] 
    LEFT OUTER JOIN (SELECT 
     [Extent3].[ID] AS [ID], 
     [Extent3].[PicklistCode] AS [PicklistCode] 
     FROM [dbo].[PicklistDetails] AS [Extent3] 
     WHERE [Extent1].[DiameterID] = [Extent3].[ID]) AS [Project1] ON 1 = 1 
    LEFT OUTER JOIN (SELECT 
     [Extent4].[ID] AS [ID], 
     [Extent4].[PicklistCode] AS [PicklistCode] 
     FROM [dbo].[PicklistDetails] AS [Extent4] 
     WHERE [Extent1].[ScheduleID] = [Extent4].[ID]) AS [Project2] ON 1 = 1 
    LEFT OUTER JOIN (SELECT 
     [Extent5].[ID] AS [ID], 
     [Extent5].[PicklistCode] AS [PicklistCode] 
     FROM [dbo].[PicklistDetails] AS [Extent5] 
     WHERE [Extent1].[DiameterID] = [Extent5].[ID]) AS [Project3] ON 1 = 1 
    LEFT OUTER JOIN (SELECT 
     [Extent6].[ID] AS [ID], 
     [Extent6].[PicklistCode] AS [PicklistCode] 
     FROM [dbo].[PicklistDetails] AS [Extent6] 
     WHERE [Extent1].[ScheduleID] = [Extent6].[ID]) AS [Project4] ON 1 = 1 
    WHERE (([Project1].[PicklistCode] + N'-' + [Project2].[PicklistCode]) = [Extent2].[PicklistCode]) OR (([Project3].[PicklistCode] + N'-' + [Project4].[PicklistCode] IS NULL) AND ([Extent2].[PicklistCode] IS NULL)) 
) 
LEFT OUTER JOIN [dbo].[PicklistDetails] AS [Extent7] ON [Extent1].[DiameterID] = [Extent7].[ID] 
LEFT OUTER JOIN [dbo].[PicklistDetails] AS [Extent8] ON [Extent1].[ScheduleID] = [Extent8].[ID] 
WHERE [Extent1].[Active] = 1 

我可以在SQL相同的结果要快得多使用此查询:

select pi.Active, pi.id, pi.IsCategory, pi.Name, diameter.Value1 as diameter, nt.Value1 as thickness, diameter.PicklistCode + '-' + schedule.PicklistCode as thicknesscode 
from ProductItem pi 
    inner join PicklistDetails diameter on diameter.id = pi.DiameterID 
    inner join PicklistDetails schedule on schedule.id = pi.ScheduleID 
    inner join PicklistDetails nt on nt.PicklistCode = diameter.PicklistCode + '-' + schedule.PicklistCode 
where pi.Active = 1 

我知道我可以运行该SQL直接查询,但我想看看我是否可以让linq查询运行得更快。正如我所提到的,linq查询运行约3秒钟,sql查询运行时间小于1秒。

我检查执行计划和两个主要的项目如下 41%排序([ProductItem] .DiameterID升序,[ProductItem] .ScheduleID升序,[PicklistDetails] .PicklistCode升序) 49%行计数阀芯(懒惰的线轴)我不完全确定这是一个什么。

+0

你检查了生成的SQL的外观吗? – MarcinJuraszek

+0

你看过linq语句生成的SQL吗?它通常会给你一个提示。 'myContext.GetGeneratedSQL(results);' – McAden

+0

我假设有一个基于此的sql服务器。如果是这样,那个连接看起来很慢。有时加入文字可能会很慢。 – clhereistian

回答

1

Linq to entities如果您不知道如何正确使用,可能会非常慢。下面是一些将真正提高你的表现技巧:

1)避免把所有的DB对象到一个单一的实体模型

2)禁用变化对实体跟踪,如果没有必要

3的)。使用预生成视图来减少响应时间为第一请求

4.)避免提取所有字段如果不需要

5.)选择适当的集合用于数据操纵

6)使用编译的查询需要的地方

7)只检索所需数量的记录

8)避免使用含有

这2点和5是非常重要的。之后,你也可以考虑8,7和休息。您可以始终使用ToTraceString()来检查您的linq查询发送到数据库的内容。它会给你等价的sql查询,你可以分析和提高性能。您可以参考以下链接了解更多详情:

[链接] http://www.dotnet-tricks.com/Tutorial/entityframework/J8bO140912-Tips-to-improve-Entity-Framework-Performance.html

1

我会在这里怀疑罪魁祸首是你的计算值一起,从两个单独的表(直径和附表)拉动值时尤为如此。 SQL无法充分利用其索引以及该结构。根据生成的SQL检查该连接的执行计划。最终,我最好的建议是通过将计算出的选择列表代码非规范化并将其放入productitem表中来移除查询计算,但是不知道您的数据模型是否足够了解这是否合理。

+0

我已经添加了一些信息。我能够使用SQL查询来写这个,并看到更好的性能。不幸的是,我不能在这种情况下使数据非规范化。 – mark