C# LINQ类似查询的执行时间完全不同

C# LINQ类似查询的执行时间完全不同,c#,sql,linq,C#,Sql,Linq,我对实体框架和Linq有一个非常奇怪的问题。我的第一个查询如下所示: from account in context.account join access in context.access on account.Id equals access.IdAccount join group in context.group on access.IdGroup equals group.Id where account.IdUser == idUser &a

我对实体框架和Linq有一个非常奇怪的问题。我的第一个查询如下所示:

    from account in context.account
    join access in context.access on account.Id equals access.IdAccount
    join group in context.group on access.IdGroup equals group.Id
    where account.IdUser == idUser
    && access.Date > DateTime(2014,02,21)
    && group.Access > 0
    select access
执行时没有任何问题。但添加附加条件(access.Status>0)后,同样的问题会执行很长时间。30秒后,它仍在运行:

    from account in context.account
    join access in context.access on account.Id equals access.IdAccount
    join group in context.group on access.IdGroup equals group.Id
    where account.IdUser == idUser
    && access.Status > 0
    && access.Date > DateTime(2014,02,21)
    && group.Access > 0
    select access
状态列不是计算列。从返回的SQL查询

    ((System.Data.Objects.ObjectQuery)result).ToTraceString();
完全不同。查询中的此附加访问状态条件在哪里可能有问题

生成的SQL查询。列的名称不同,因为在LINQ示例中,它们是从波兰语翻译成英语的。第一个问题是:

    SELECT
    `Filter1`.`IdDostep`, 
    `Filter1`.`IDKONTO1` AS `IdKonto`, 
    `Filter1`.`IndeksOms`, 
    `Filter1`.`IdGrupa`, 
    `Filter1`.`DataUtw`, 
    `Filter1`.`DataMod`, 
    `Filter1`.`DataOd`, 
    `Filter1`.`DataDo`, 
    `Filter1`.`Znacznik`, 
    `Filter1`.`Kalendarz`, 
    `Filter1`.`Komplet`, 
    `Filter1`.`Access`
    FROM (SELECT
    `Extent1`.`IdKonto`, 
    `Extent1`.`IdAbonenta`, 
    `Extent1`.`NrAbonenta`, 
    `Extent1`.`NrFaktury`, 
    `Extent1`.`DataFaktury`, 
    `Extent1`.`Login`, 
    `Extent1`.`Password`, 
    `Extent1`.`Notatka`, 
    `Extent1`.`IPAdres`, 
    `Extent1`.`Email`, 
    `Extent1`.`LastLogin`, 
    `Extent1`.`LastIP`, 
    `Extent1`.`Session`, 
    `Extent1`.`Regulamin`, 
    `Extent1`.`RegulaminDataAkceptacji`, 
    `Extent1`.`Powiadomienie`, 
    `Extent1`.`Gratis`, 
    `Extent1`.`PrzyEmail`, 
    `Extent1`.`PrzyIdPytanie`, 
    `Extent1`.`PrzyOdpowiedz`, 
    `Extent1`.`PrzyStatus`, 
    `Extent1`.`PrzySesja`, 
    `Extent1`.`IdKod`, 
    `Extent1`.`szerokosc`, 
    `Extent1`.`wysokosc`, 
    `Extent1`.`serwis`, 
    `Extent1`.`Nzam`, 
    `Extent1`.`parent`, 
    `Extent1`.`RegulaminLogowanie`, 
    `Extent1`.`NoBaners`, 
    `Extent1`.`KontoPromocyjne`, 
    `Extent2`.`IdDostep`, 
    `Extent2`.`IdKonto` AS `IDKONTO1`, 
    `Extent2`.`IndeksOms`, 
    `Extent2`.`IdGrupa`, 
    `Extent2`.`DataUtw`, 
    `Extent2`.`DataMod`, 
    `Extent2`.`DataOd`, 
    `Extent2`.`DataDo`, 
    `Extent2`.`Znacznik`, 
    `Extent2`.`Kalendarz`, 
    `Extent2`.`Komplet`, 
    `Extent2`.`Access`
    FROM `konto` AS `Extent1` INNER JOIN `dostep` AS `Extent2` ON `Extent1`.`IdKonto` = `Extent2`.`IdKonto`
     WHERE `Extent2`.`DataDo` > @gp1) AS `Filter1` INNER JOIN `grupa` AS `Extent3` ON `Filter1`.`IdGrupa` = `Extent3`.`IdGrupa`
     WHERE (`Filter1`.`NrAbonenta` = @p__linq__0) AND (`Extent3`.`Access` > 0)
第二个问题是:

    SELECT
    `Filter1`.`IdDostep`, 
    `Filter1`.`IDKONTO1` AS `IdKonto`, 
    `Filter1`.`IndeksOms`, 
    `Filter1`.`IdGrupa`, 
    `Filter1`.`DataUtw`, 
    `Filter1`.`DataMod`, 
    `Filter1`.`DataOd`, 
    `Filter1`.`DataDo`, 
    `Filter1`.`Znacznik`, 
    `Filter1`.`Kalendarz`, 
    `Filter1`.`Komplet`, 
    `Filter1`.`Access`
    FROM (SELECT
    `Extent1`.`IdKonto`, 
    `Extent1`.`IdAbonenta`, 
    `Extent1`.`NrAbonenta`, 
    `Extent1`.`NrFaktury`, 
    `Extent1`.`DataFaktury`, 
    `Extent1`.`Login`, 
    `Extent1`.`Password`, 
    `Extent1`.`Notatka`, 
    `Extent1`.`IPAdres`, 
    `Extent1`.`Email`, 
    `Extent1`.`LastLogin`, 
    `Extent1`.`LastIP`, 
    `Extent1`.`Session`, 
    `Extent1`.`Regulamin`, 
    `Extent1`.`RegulaminDataAkceptacji`, 
    `Extent1`.`Powiadomienie`, 
    `Extent1`.`Gratis`, 
    `Extent1`.`PrzyEmail`, 
    `Extent1`.`PrzyIdPytanie`, 
    `Extent1`.`PrzyOdpowiedz`, 
    `Extent1`.`PrzyStatus`, 
    `Extent1`.`PrzySesja`, 
    `Extent1`.`IdKod`, 
    `Extent1`.`szerokosc`, 
    `Extent1`.`wysokosc`, 
    `Extent1`.`serwis`, 
    `Extent1`.`Nzam`, 
    `Extent1`.`parent`, 
    `Extent1`.`RegulaminLogowanie`, 
    `Extent1`.`NoBaners`, 
    `Extent1`.`KontoPromocyjne`, 
    `Extent2`.`IdDostep`, 
    `Extent2`.`IdKonto` AS `IDKONTO1`, 
    `Extent2`.`IndeksOms`, 
    `Extent2`.`IdGrupa`, 
    `Extent2`.`DataUtw`, 
    `Extent2`.`DataMod`, 
    `Extent2`.`DataOd`, 
    `Extent2`.`DataDo`, 
    `Extent2`.`Znacznik`, 
    `Extent2`.`Kalendarz`, 
    `Extent2`.`Komplet`, 
    `Extent2`.`Access`
    FROM `konto` AS `Extent1` INNER JOIN `dostep` AS `Extent2` ON `Extent1`.`IdKonto` = `Extent2`.`IdKonto`
     WHERE ((`Extent2`.`Komplet`) > 0) AND (`Extent2`.`DataDo` > @gp1)) AS `Filter1` INNER JOIN `grupa` AS `Extent3` ON `Filter1`.`IdGrupa` = `Extent3`.`IdGrupa`
     WHERE (`Filter1`.`NrAbonenta` = @p__linq__0) AND (`Extent3`.`Access` > 0)     

问题不应该出现在linq中,而是数据库中sql语句的底层执行。可能第一个查询只使用索引执行,而第二个查询扫描表

建议要解决您的问题,请使用ToTraceString()查看两个查询的执行计划,并了解您的问题。如果你需要额外的帮助,发布查询计划,我们会帮助你

编辑:

正如您可能从sql查询中看到的,它们没有那么大的不同,只是在内部查询筛选器中有所不同:

第一个查询包含以下内容:

    WHERE  Extent2.datado > @gp1) AS Filter1 
第二条:

    WHERE  ( ( Extent2.komplet ) > 0 ) 
           AND ( Extent2.datado > @gp1 )) AS Filter1 

所以,即使你有所有的索引,也不意味着它们是好的索引。如果每个列都有索引,SQL可能只选择其中一个。也许你需要复习一下。因此,正如我前面所建议的,检查每个查询的查询执行计划,看看瓶颈在哪里。

能否添加
ToTraceString()
的结果?是否比较了查询生成的sql?是
access.Status
索引了吗?是的,access.Staus索引了。正如我刚才添加的sql查询中所示,查询完全不同,而我只添加了一个列条件。为什么这些查询如此不同?@torpederos您确定您发布的是上述linq的正确SQL查询吗?因为linq有两个“动态”过滤器,
Date
IdUser
,所以实际上只传递了一个。请重新检查您的
结果
变量是否为linq表达式您的回答非常有用。我忘了提到整个问题适用于MySql数据库。当我使用“explain”运行查询时,我发现“派生”查询不使用任何索引,唯一的解决方案是尝试修改sql查询。经过几次尝试后,我发现LINQ构造可以产生最佳的sql查询。