我对Entity Framework和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();
完全不同。这个额外的access.Status条件在查询中可能出现问题?
生成的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)
答案 0 :(得分:4)
问题不应该在linq中,而应该是数据库中sql语句的底层执行。可能第一个查询仅使用索引执行,而第二个查询扫描表。
建议解决您的问题,查看两个查询的执行计划,使用ToTraceString()并了解您的问题。如果您需要额外的帮助,请发布该查询计划,我们会帮您解决。
修改强>
正如您从sql查询中看到的那样,它们没有那么不同,它们只在内部查询过滤器中有所不同:
第一个查询包含:
WHERE Extent2.datado > @gp1) AS Filter1
第二个:
WHERE ( ( Extent2.komplet ) > 0 )
AND ( Extent2.datado > @gp1 )) AS Filter1
所以,即使你有所有索引并不意味着它们是好的索引。如果每个列都有一个索引,则SQL可能只选择其中一个列。可能你需要检查它们。所以,就像我之前建议的那样,检查每个查询执行计划,看看你的瓶颈在哪里。