C# - LINQ - 2种查询方式之间的性能

时间:2013-09-23 20:45:54

标签: c# linq optimization left-join

我必须创建一个连接3个IEnumerable(2个数据表,一个List)的LINQ查询。我还必须“外连接”我的2个连接。

我真的很喜欢第二个,因为它比SQL更可见。但是我遇到了性能问题(比同样的第一个问题长了3倍) - 那里的可读性更低,但速度更快。

有人可以向我解释一下我可以做些什么来优化第二个查询,以及为什么它们如此不同,但返回相同的数据(我是LINQ的新手,并且很难理解每个LINQ-TO -SQL / LAMBDA / SAMBA subtilities

旧的,非常快,但不太可能

 var Detailled_payroll = 
        from MainData in dt_BasicPayrollData.AsEnumerable()
           //joining (Externalize later...) with a list of days
           join MyDays in gdt_Liste_JourFérié 
              on MainData.Field<DateTime>("DENTREE") equals MyDays 
                  into MyDays_join //why?
           //joining (Externalize later...) with a list (datatable) of things
           join MyFilter in gdt_MyFilter.AsEnumerable()
              on MainData.Field<string>("KEY") equals MyFilter.Field<string>("KEY") 
                  into MyFilter_join   //why?

           //I think we "outer join" here, forcing the existing of a missing join                             
           from MyDays in MyDays_join.DefaultIfEmpty()
           from MyFilter in MyFilter_join.DefaultIfEmpty()

           let tmp = MainData.Field<string>("CEmploye") //dont remember why..

           select new Blabla()
           { 
                 EmpNumber=MainData.Field<string>("NoEmploye"),
                 IsInSpecialDays = MyDays == Default(DateTime) ? "NO" : "YES",
                 KeyWasFound = MyFilter == null ? "NO" : "YES"
           }

这是“新”的:

    var Detailled_payroll = 
        from MainData in dt_BasicPayrollData.AsEnumerable()
        //joining (and externalize...) with a list (datatable) of things
        from MyFilter in MyGlobalVariable.gdt_FiltreEnCours.AsEnumerable()
           .Where(x => x.Field<string>("KEY") == MainData.Field<string>("KEY"))
           .DefaultIfEmpty()
        //joining (and externalize...) with a list (List<DateTime>) of days
        from MyDays in gdt_Liste_JourFérié  
           .Where(x => x == MainData.Field<DateTime>("DENTREE"))
           .DefaultIfEmpty()

        select new Blabla()
          { 
                 EmpNumber=MainData.Field<string>("NoEmploye"),
                 IsInSpecialDays = MyDays == Default(DateTime) ? "NO" : "YES",
                 KeyWasFound = MyFilter == null ? "NO" : "YES"
           }
  • “旧”查询以3秒的时间返回结果。
  • “new”查询以10秒的时间返回结果。

两者都有完全相同的结果数据。

有什么想法吗?

1 个答案:

答案 0 :(得分:4)

总之,在你加入的第一个中,在第二个你有笛卡尔积然后你过滤它。