Linq C#,与多个查找相比,连接的性能更低
我有一个旧版本的代码,正在执行多重查找。我需要一些额外的字段,所以我重写了它来进行几个连接,并立即返回我需要的所有内容。我原以为这会有更好的性能,但当用秒表测试时,情况并非如此,而且速度相当慢。我是否无意中对我的查询做了一些错误 旧代码 新代码Linq C#,与多个查找相比,连接的性能更低,c#,performance,linq,join,C#,Performance,Linq,Join,我有一个旧版本的代码,正在执行多重查找。我需要一些额外的字段,所以我重写了它来进行几个连接,并立即返回我需要的所有内容。我原以为这会有更好的性能,但当用秒表测试时,情况并非如此,而且速度相当慢。我是否无意中对我的查询做了一些错误 旧代码 新代码 记录在两个查询之间生成的SQL。查看针对数据库生成的结果集。另外,是否尝试多次运行查询?EntityFramework在第一次查询时尤其慢,在同一查询的后续运行时则更快。返回了多少项?返回了41项。我确实试过并运行了几次,注意到了波动,它们现在更接近了,
记录在两个查询之间生成的SQL。查看针对数据库生成的结果集。另外,是否尝试多次运行查询?EntityFramework在第一次查询时尤其慢,在同一查询的后续运行时则更快。返回了多少项?返回了41项。我确实试过并运行了几次,注意到了波动,它们现在更接近了,相距只有50毫秒左右,但通常旧代码似乎赢得了大多数尝试。我想检查它生成的SQL只是不确定如何生成。第一个查询似乎检索不到相同的数据,特别是
游戏
相关信息。另外,您最好使用导航属性,因为连接的基数不太清楚,因此GROUPBY操作符可能是多余的。
// ===============================old
var watchOld = System.Diagnostics.Stopwatch.StartNew();
var def = context.FDataMLBPlayers.Where(d => d.Status.Trim().ToLower().Equals("active") && d.Position.Trim().ToLower().Equals(position.ToLower())).OrderBy(d => d.Team);
foreach (var dd in def)
{
bool addPlayer = false;
foreach (var tm in teams)
{
if (tm.Trim().Equals(dd.Team.Trim()))
{
addPlayer = true;
break;
}
}
if (!addPlayer) continue;
Player player = new Player();
player.Name = dd.FirstName.Trim() + " " + dd.LastName.Trim();
player.LastName = dd.LastName.Trim();
player.Number = dd.Jersey.HasValue ? dd.Jersey.Value : 0;
player.PlayerID = dd.PlayerID;
player.Points = 0;
player.Position = (dd.Position == null) ? "" : dd.Position.Trim();
player.Score = 0;
player.Status = "Active";//DOROC dd.CurrentStatus;
player.Team = dd.Team.Trim();
htop ht = GetOpposingTeam(dd.Team.Trim()); //another lookup
player.OpposingTeam = ht.OpposingTeam;
player.PhotoUrl = dd.PhotoUrl.Trim();
player.IsHomeTeam = ht.IsHomeTeam;
if (dd.Position != null)
{
list.Add(player);
}
}
watchOld.Stop();
var oldTime = watchOld.ElapsedMilliseconds; // 227 ms
// ========================================== new
var watchNew = System.Diagnostics.Stopwatch.StartNew();
var def2 = (from p in context.FDataMLBPlayers
join g in context.FDataMLBPlayerGames on p.PlayerID equals g.PlayerID
join t in context.FDataMLBTeams on g.OpponentID equals t.TeamID
where p.Status.Trim().ToLower().Equals("active")
&& p.Position.Trim().ToLower().Equals(position.ToLower())
&& teams.Contains(p.Team)
group new { p, g, t }
by new { p.PlayerID } into pgt
let fod = pgt.FirstOrDefault()
select new Player
{
DateTime = fod.g.DateTime.Value,
IsHomeTeam = fod.g.HomeOrAway.ToLower().Equals("home") ? true : false,
LastName = fod.p.LastName,
Name = fod.p.FirstName.Trim() + " " + fod.p.LastName.Trim(),
Number = fod.p.Jersey.HasValue ? fod.p.Jersey.Value : 0,
OpposingTeam = fod.t.Name,
PhotoUrl = fod.p.PhotoUrl,
PlayerID = fod.p.PlayerID,
Points = 0,
Position = fod.p.Position,
Score = 0,
Started = fod.g.Started.Value.Equals(1) ? true : false,
Status = fod.p.Status,
Team = fod.p.Team,
}
).ToList();
list = def2;
watchNew.Stop();
var newTime = watchNew.ElapsedMilliseconds; // 399 ms