从2个查询中选择更好的查询,两者都返回相同的结果

时间:2011-09-06 22:48:11

标签: c# sql sql-server linq sql-server-2008

我有两个不同的sql查询,一个由我编写,一个由C#自动生成,当与linq一起使用时,两者都给出相同的结果。

我不确定选择哪一个,Iam正在寻找

  1. 当所有人都返回相同的结果(最优化的查询)时,最好的方法是选择多个查询中的一个。
  2. 出于我的疑问(下面写着),我应该选择哪一个。
  3. 手写

    select * from People P
    inner join  SubscriptionItemXes S
    on
    P.Id=S.Person_Id
    inner join FoodTagXFoods T1
    on T1.FoodTagX_Id = S.Tag2
    
    inner join FoodTagXFoods T2
    on T2.FoodTagX_Id = S.Tag1
    
    inner join Foods F
    on
    F.Id= T1.Food_Id and F.Id= T2.Food_Id
    
    where p.id='1'
    

    由LINQ

    自动生成
    SELECT 
    [Distinct1].[Id] AS [Id], 
    [Distinct1].[Item] AS [Item]
    FROM ( SELECT DISTINCT 
        [Extent2].[Id] AS [Id], 
        [Extent2].[Item] AS [Item]
        FROM    [dbo].[People] AS [Extent1]
        CROSS JOIN [dbo].[Foods] AS [Extent2]
        INNER JOIN [dbo].[FoodTagXFoods] AS [Extent3] 
        ON [Extent2].[Id] = [Extent3].[Food_Id]
        INNER JOIN [dbo].[SubscriptionItemXes] AS [Extent4] 
        ON [Extent1].[Id] = [Extent4].[Person_Id]
        WHERE (N'rusi' = [Extent1].[Name]) AND ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[FoodTagXFoods] AS [Extent5]
            WHERE ([Extent2].[Id] = [Extent5].[Food_Id]) 
                AND ([Extent5].[FoodTagX_Id] = [Extent4].[Tag1])
        )) AND ( EXISTS (SELECT 
            1 AS [C1]
            FROM [dbo].[FoodTagXFoods] AS [Extent6]
            WHERE ([Extent2].[Id] = [Extent6].[Food_Id]) 
                AND ([Extent6].[FoodTagX_Id] = [Extent4].[Tag2])
        ))
    )  AS [Distinct1]
    

    执行计划结果

    手写:查询成本(相对于批次):33%

    Linq生成:查询成本(相对于批次):67%

3 个答案:

答案 0 :(得分:6)

我发现两个不同的查询,一个手写和一个由Linq生成的查询可能看起来大不相同,但实际上,当您在SSMS中分析查询计划时,您会发现实际上它们几乎相同。

您需要在启用了Display Actual Execution Plan的SSMS中实际运行这些查询,并分析不同的计划。这是正确分析两者并找出哪个更好的唯一方法。

一般来说,Linq实际上非常善于生成有效的查询;即使实际的SQL本身非常丑陋(在某些情况下,如果他们有时间,那就是人类会写的那种SQL!)。如果当然,那说,它也可以产生一些猪!

此外,要求SO帮助在这么多表上执行查询,这对我们来说充满了问题,因为它将受到索引的控制:)

答案 1 :(得分:3)

但他们并没有完全相同的东西......第一个查询抓住每一个(SELECT *),而LINQ将提取你真正想要的东西(id和item)。你可能会说琐碎但是回传大量从未使用过的数据是浪费带宽并且会使你的应用程序显得迟钝。此外,LINQ查询似乎做得更多,可能是也可能不是正确的解决方案,特别是当数据填充到FoodTagXFoods中时

至于哪个表现更好,我无法告诉你没有像两个查询中的实际查询计划和/或统计结果。我的钱是手写的,但也许是因为我喜欢我的手。

答案 2 :(得分:0)