C# LINQ类似查询的执行时间完全不同
我对实体框架和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
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查询。