쿼리를 수행하는 데 더 많은 Entity Framework 관련 테스트 방법을 테스트하기 위해 Github 프로젝트를 수정했습니다.Entity Framework 6 비동기 메서드 성능과 동기화 메서드
모델 :
[Table("Player")]
public partial class Player
{
public int Id { get; set; }
[Required]
[StringLength(200)]
public string FirstName { get; set; }
[Required]
[StringLength(200)]
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
public int TeamId { get; set; }
public virtual Team Team { get; set; }
}
[Table("Team")]
public partial class Team
{
public Team()
{
Players = new HashSet<Player>();
}
public int Id { get; set; }
[Required]
[StringLength(200)]
public string Name { get; set; }
public DateTime FoundingDate { get; set; }
public int SportId { get; set; }
public virtual ICollection<Player> Players { get; set; }
public virtual Sport Sport { get; set; }
}
[Table("Sport")]
public partial class Sport
{
public Sport()
{
Teams = new HashSet<Team>();
}
public int Id { get; set; }
[StringLength(100)]
public string Name { get; set; }
public virtual ICollection<Team> Teams { get; set; }
}
내가 무엇을 테스트입니다 것은 이런 것들이다 :
EF "조정"- FirstOrDefault()와 ToList()
context.Players.FirstOrDefault(x => x.Id == id);
context.Players.AsNoTracking().Where(x => x.TeamId == teamId).ToList();
context.Teams.AsNoTracking().Include(x => x.Players).Where(x => x.SportId == sportId).ToList();
EF "비동기"- DTO에 FirstOrDefaultAsync()와 선택과 ToListAsync()
await context.Players.FirstOrDefaultAsync(x => x.Id == id);
await context.Players.AsNoTracking().Where(x => x.TeamId == teamId).ToListAsync();
await context.Teams.AsNoTracking().Include(x => x.Players).Where(x => x.SportId == sportId).ToListAsync();
EF "동기화"DTO에 선택과
context.Players.Select(p => new PlayerDTO()
{
Id = p.Id,
FirstName = p.FirstName,
DateOfBirth = p.DateOfBirth,
LastName = p.LastName,
TeamId = p.TeamId
}).FirstOrDefault(x => x.Id == id);
context.Players.Where(x => x.TeamId == teamId).Select(p => new PlayerDTO()
{
Id = p.Id,
FirstName = p.FirstName,
DateOfBirth = p.DateOfBirth,
LastName = p.LastName,
TeamId = p.TeamId
}).ToList();
context.Teams.Where(x => x.SportId == sportId).Select(t => new TeamDTO()
{
Id = t.Id,
FoundingDate = t.FoundingDate,
Name = t.Name,
SportId = t.SportId,
Players = t.Players.Select(p => new PlayerDTO()
{
Id = p.Id,
FirstName = p.FirstName,
DateOfBirth = p.DateOfBirth,
LastName = p.LastName,
TeamId = p.TeamId
}).ToList()
}).ToList();
EF "비동기" 객체를 객체
await context.Players.Select(p => new PlayerDTO()
{
Id = p.Id,
FirstName = p.FirstName,
DateOfBirth = p.DateOfBirth,
LastName = p.LastName,
TeamId = p.TeamId
}).FirstOrDefaultAsync(x => x.Id == id);
await context.Players.Where(x => x.TeamId == teamId).Select(p => new PlayerDTO()
{
Id = p.Id,
FirstName = p.FirstName,
DateOfBirth = p.DateOfBirth,
LastName = p.LastName,
TeamId = p.TeamId
}).ToListAsync();
await context.Teams.Where(x => x.SportId == sportId).Select(t => new TeamDTO()
{
Id = t.Id,
FoundingDate = t.FoundingDate,
Name = t.Name,
SportId = t.SportId,
Players = t.Players.Select(p => new PlayerDTO()
{
Id = p.Id,
FirstName = p.FirstName,
DateOfBirth = p.DateOfBirth,
LastName = p.LastName,
TeamId = p.TeamId
}).ToList()
}).ToListAsync();
제 결과는 상당히 귀찮습니다. 주로 MS가 EF의 비동기 부분을 홍보하기 때문에.
내 결과 : (밀리 초 단위) 스포츠의
수 : 8, 팀 수 : 30, 플레이어 수 : 100
EntityFrameworkAsyncDTO Results
Run # Player by ID Players per Team Teams per Sport
0 1,46 3,47 35,88
1 1,04 3 33
2 1,02 3,3 33,75
3 1,03 3 31,75
4 1,1 3,27 31,38
EntityFrameworkAsync Results
Run # Player by ID Players per Team Teams per Sport
0 1,17 3,53 57
1 1,01 3 48,62
2 0,99 3,03 47,88
3 1,02 3,07 51
4 1 3,03 48,88
EntityFrameworkDTO Results
Run # Player by ID Players per Team Teams per Sport
0 0,02 3 13,25
1 0,01 2,8 13,12
2 0,15 2,97 13,25
3 0,02 2,9 13,25
4 0,05 2,8 13,12
EntityFramework Results
Run # Player by ID Players per Team Teams per Sport
0 0,01 2,27 28,38
1 0,01 2,4 28,25
2 0 2,13 28,5
3 0,01 2,17 27,5
4 0,01 2,13 29
ADONET Results
Run # Player by ID Players per Team Teams per Sport
0 0 2,03 11,75
1 0 2 12,62
2 0 2 11,38
3 0 2 12,38
4 0 2 11,25
내가 추가 한
/편집하여 ADO.NET 시간 결과 목록을 참조로 사용합니다.
제 질문은 :로드 시간이 너무 다르기 때문에 제 쿼리에 문제가 있습니까?
실제로 실행중인 시스템에서 모든 비동기식 DB 호출을 동기화 호출로 변경했으며 내 통계에서 볼 수있는 것은 시스템이 DB 호출의 50 % 속도 증가를 보았습니다. 이것은 SignalR을 통해 연결된 100-120 명의 현재 사용자가있는 시스템입니다. DB가 매우 무겁습니다.
First vs. FirstAsync와 FindAsync를 비교할 수 있습니다. First와 Find는 꽤 다른 양의 일을합니다. – vittore
또한 'Async'는 "빠름"이 아닙니다. 그것은 많은 오버 헤드를 추가합니다. 그러나 네트워크 통신을 기다리는 시간을 사용할 수 있습니다. – vittore
Async/Await에 오버 헤드가 있다는 것을 알고 있지만 EF를 통한 SQL 호출이 2-4 배 느려질 것이라고 생각하지 않습니다. –