我在EF中有一个查询,查询效果很差,无法真正解释原因。查询大约需要30秒(!)才能返回20行数据。
编辑:我正在尝试实现以下目标:CandidateAssignments是一种扩展的链接表,其中包含有关哪个候选人属于哪个项目(CandidateId-ProjectId)以及得分的信息。我想简单地返回得分最高的候选对象(使用相应的跳过),其中要返回的对象类型不是完整的EntityType,而是较小的版本,仅获取几个字段(这就是为什么我选择其他类型的原因{ {1}}。
CompactProfile
Candidates表有约6万行,这虽然有点,但绝对不成问题。
我已使用var candidates = _db
.CandidateAssignments
.OrderByDescending(a => a.Score)
.Skip(skip)
.Take(20)
.Select(a => _db.Candidates.FirstOrDefault(c => c.Guid == a.CandidateId))
.Select(c => new CompactProfile
{
Id = c.Guid,
FirstName = c.FirstName,
LastName = c.LastName,
Image = c.Image,
City = c.City,
Company = c.Company,
Degree = c.Degree,
Haves = c.Haves,
JobTitle = c.JobTitle,
Languages = c.Languages,
Lattitude = c.Latitude,
Longitude = c.Longitude,
YearsOfExperience = c.YearsOfExperience,
ZipCode = c.ZipCode
})
.ToList();
属性在Candidate.Guid
上放置了一个索引(代码优先迁移)。
该数据库托管在Azure上,因此我可以看到针对该数据库执行的SQL查询:
[Index]
不幸的是,我的SQL技能不足以在这里识别问题。
如何重建此查询以获得合理的性能?
答案 0 :(得分:2)
我猜您对表扫描执行的子查询是原因。我想您可以尝试使用类似方法获得相同的结果(根据他们的分配排名前20名的候选人?)
var candidates = (from a in _db.CandidateAssignments
join c in _db.Candidates on c.Guid equals a.CandidateId
orderby a.Score Descending
select c)
.Skip(skip)
.Take(20)
.Select(c => ...)
.ToList();
答案 1 :(得分:0)
除了Janne的回答外,这里还有LINQ版本,该版本将查询时间缩短到大约200ms:
var candidates = _db.CandidateAssignments
.OrderByDescending(a => a.Score)
.Skip(skip)
.Take(20)
.Join(_db.Candidates, a => a.CandidateId, c => c.Guid, (a, c) => new CompactProfile
{
Id = c.Guid,
FirstName = c.FirstName,
LastName = c.LastName,
Image = c.XingImage64,
City = c.City,
Company = c.Company,
Degree = c.Degree,
Haves = c.Haves,
JobTitle = c.JobTitle,
Languages = c.Languages,
Lattitude = c.Latitude,
Longitude = c.Longitude,
YearsOfExperience = c.YearsOfExperience,
ZipCode = c.ZipCode
})
.ToList();