>

EF Core 3.1은 열별로 필터링 할 때 성능이 저하 된 쿼리 (인덱스 누락으로 인해)를 생성합니다.

문제를 일으키는 열은 다음과 같습니다.

builder.Property(p => p.Id)
            .HasConversion(
                value => value.Value,
                dbValue => new LocationId(dbValue)
            )
            .HasMaxLength(50);

LocationId는 값 객체입니다

쿼리는 다음 코드에서 생성됩니다.

_repository.Query.FirstOrDefaultAsync(l => l.Id == "DD212334234");

여기서 _repository.Query는 기본적으로 DbSet of Locations입니다.

생성 된 쿼리는 다음과 같습니다.

SELECT TOP 1 * FROM [locations] as [l] WHERE CAST([l].[Id] AS nvarchar(max)) = 'DD212334234'

CAST 대 nvarchar (max)에 유의하십시오. 열 ID는 nvarchar (50)이며 색인이 있습니다. 2.5M 레코드에 대한 위의 쿼리는 약 1.2 초 동안 실행됩니다. CAST를 제거하고 쿼리를 실행하면 100ms 동안 완료됩니다.

이것을 분류하는 데 도움이 될 것입니다.

업데이트 : 내 DbContext는 다음으로 빌드됩니다.

builder.UseSqlServer(options.ConnectionString, x =>
                    {
                        x.MigrationsAssembly(assemblyName);
                        x.MigrationsHistoryTable($"__migrations_{contextName}");
                        x.UseNetTopologySuite();
                    });

또 다른 업데이트 :

.HasConversion (...)을 주석 처리하면 CAST없이 쿼리가 생성됩니다. LocationId는 다음과 같습니다.

public class LocationId : ValueObject
{
    private LocationId(string value)
    {
        Value = value.ToUpperInvariant();
    }
    public string Value { get; }
    public static implicit operator string(LocationId c) => c.Value;
    public static explicit operator LocationId(string s) => new LocationId(s);
     ...
}

  • 답변 # 1

    문제는 운영자에 의해 발생합니다

    public static implicit operator string(LocationId c) => c.Value;
    public static explicit operator LocationId(string s) => new LocationId(s);
    
    

    표정을 강조하다

    l => l.Id == "DD212334234"
    
    

    실제로

    l => (string)l.Id == "DD212334234"
    
    

    번역 된 SQL에서 CAST로 연결됩니다.

    처음에는 테스트에서 두 가지 변환이 모두 암시 되었기 때문에 재현 할 수 없었습니다.

    public static implicit operator string(LocationId c) => c.Value;
    public static implicit operator LocationId(string s) => new LocationId(s);
    
    

    위의 표현은 실제로

    l => l.Id == (LocationId)"DD212334234"
    
    

    생성 된 SQL에 CAST를 도입하지 않습니다.

    해결책은 운영자를 LocationId 암시 적 또는 명시 적 캐스트 사용

    l => l.Id == (LocationId)"DD212334234"
    
    

    또는 LocationId 건설자

    l => l.Id == new LocationId("DD212334234")
    
    

    또는 LocationId 변하기 쉬운.

    또는 일반적으로 클라이언트 유형 비교.

  • 이전 c# - net core 31 - 면도기 페이지 및 api 컨트롤러에 대한 엔드 포인트 라우팅
  • 다음 cdo climate - cdo에서 이중선 보간을 사용하여 NetCDF 파일 리그 리딩