Entity Framework Core - 동시에 실행된 쿼리는 다른 환경에서 다르게 작동합니다.

코코롤

문제 : 동시에 시작된 Entity Framework 호출이 처리하는 데 점점 더 길어지는 것을 확인했습니다. 프로그램은 EF 2.2가 포함된 .NET Core 2.2입니다.

다음은 동작을 보여주는 로그의 예입니다.

로그의 스냅샷

30번째 쿼리에서 최대 10초까지 진행됩니다.

조사:

이것을 재현하고 테스트하기 위해 Test() 메서드를 병렬로 20번 호출하는 간단한 실행 파일을 만들었습니다. Test()는 ServiceProvider에서 범위가 지정된 컨텍스트를 가져오고 데이터베이스에 쿼리를 수행합니다. 나는 그것을 몇 번 실행했고 각 설정에 대한 3개의 결과에서 스크린샷을 보여주었습니다. 참고: Query() 메서드는 20번의 테스트 전에 한 번 실행되어 EF가 쿼리 캐시를 생성할 수 있도록 합니다.

 private async Task Test()
    {
        List<Task> tasks = new List<Task>();
        // Populate the queue.
        for (int i = 0; i < 10000; i++)
        {
            cq.Enqueue(i);
        }
        Query();
        Thread.Sleep(1000);
        Query();
        Thread.Sleep(1000);
        for (int i = 0; i < 20; i++)
        {
            tasks.Add(Task.Run(() => Query()));
        }


        await Task.WhenAll(tasks);

    }



    private async Task Query()
    {
        cq.TryDequeue(out int id);

        Log.Debug($"[{id}] {DateTime.Now.ToString("mm:ss.fff")}: started");

        using (var serviceScope = _serviceProvider.CreateScope())
        {
            var watch = new Stopwatch();
            var ctx = serviceScope.ServiceProvider.GetService<Core.Models.MyContext>();

            watch.Start();

            var quoteLineJob = await ctx.QuoteLineJobs
                .FirstOrDefaultAsync(o => o.Id == id);

            watch.Stop();

            Log.Debug($"[{id}] {DateTime.Now.ToString("mm:ss.fff")}: Quote line job loaded in {watch.ElapsedMilliseconds}ms");
            
        }
    }

나는 결과를 이해할 수 없으며 누군가가 가설을 제안할 수 있기를 바랍니다.

  • 프로덕션 클라이언트 머신에서 프로덕션 DB로 제품에서 제품으로

로딩이 점점 더 길어집니다.

  • 개발자 머신에서 프로덕션 DB로

DevToProd

그러나 동일한 데이터베이스를 적중하면 결과가 훨씬 느립니다.

  • 랜덤 서버에서 프로덕션 DB로

ServToProd

결과는 개발자의 컴퓨터에서와 매우 유사하지만 점진적으로 작동하지 않고 무작위로 작동할 확률(세 번째 결과 참조)이 50%입니다.

I would like to add that looking at a SQL Server Profiler, for all setup, the read queries take 0ms for all simultaneous queries.

As if this wasn't confusing, when I tried the same test on localhost:

  • Developer's machine to developer's DB (DB Copy from production, same data)

DevToDev

results here are random and not incremented

  • Random Server to Random Server DB

서브투서브

Again, loading times are random and not incremented

Does anyone see some patterns, and suggestions as to why Entity Framework would behave like this?

Steve Py

My first suggestion would be to determine whether the cause is EF or your service wrapper, depending on how that is implemented. Change your test to this instead and check the performance on the different environments:

var watch = new Stopwatch();
watch.Start();
using (var ctx = new YourAppDbContext(ConnectionString))
{
    var quoteLineJob = await ctx.QuoteLineJobs
        .FirstOrDefaultAsync(o => o.Id == id);
}
watch.Stop();

Log.Debug($"[{id}] {DateTime.Now.ToString("mm:ss.fff")}: Quote line job loaded in {watch.ElapsedMilliseconds}ms");
        

If this behaves more predictably then something is suss with your context scope or provider for the DbContext. (unlikely, but without seeing the code, a possibility)

If it is still somewhat variable this is probably a symptom of parallelization. While executing async code, the awaited methods will be setting resume execution points and freeing up the executing thread. .Net will be responding to requests to resume thread operations. Given these operations are already being parallelized into tasks one test would be to make the EF calls synchronously to assess whether more predictable performance comes back. The server's # of cores and overall load situation could greatly effect how 20 or more parallelized are executed.

var watch = new Stopwatch();
watch.Start();
using (var ctx = new YourAppDbContext(ConnectionString))
{
    var quoteLineJob = ctx.QuoteLineJobs
        .FirstOrDefault(o => o.Id == id);
}
watch.Stop();

Log.Debug($"[{id}] {DateTime.Now.ToString("mm:ss.fff")}: Quote line job loaded in {watch.ElapsedMilliseconds}ms");

다시 말하지만, 이는 성능 문제의 잠재적 원인을 식별하는 데 도움이 될 뿐입니다. async/ await더 나은 성능과 같지는 않지만 개별 작업은 느리게 만들지만 요청을 선택하기 전에 완료될 느리거나 빈도가 높은 작업을 기다리지 않고 더 많은 요청을 처리하기 위해 서버 전체를 더 빠르게 처리합니다. 스레드 간의 컨텍스트 전환은 각 작업이 더 느리게 작동하고 서버에 부하가 있을 때 잠재적으로 가변적으로 작동함을 의미합니다. async상당한 시간이 소요될 것으로 예상되거나 매우 자주 호출될 것으로 예상되는 작업에 대해 작업을 예약 합니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

Entity Framework는 느리게 응답하지만 생성 된 쿼리는 SqlDeveloper 워크 시트에서 빠르게 실행됩니다.

Entity Framework : LINQ 쿼리는 로컬 실행과 서버 실행간에 서로 다른 SQL을 생성합니다.

Entity Framework-다른 환경에서 다른 동작

Entity Framework는 이미 실행 된 쿼리에 대해 데이터베이스 쿼리를 다시 실행합니까?

KeyboardInterrupt는 실행에 따라 다르게 작동합니다.

Entity Framework Core에서 동적 쿼리 실행

다른 서버에서 다르게 작동하는 쿼리

Vim에서 실행되는 셸 명령이 다르게 작동합니다.

내 Entity Framework Core API는 로컬에서 제대로 작동하지만 프로덕션에서 405 오류와 함께 실패합니다.

Entity Framework를 사용하는 쿼리에서 빈 문자열 조건 반환이 작동하지 않습니다.

Entity Framework Core에서 다 대다 관계 쿼리 문제

new Date ()는 다른 환경에서 다르게 작동합니다. 그 이유는 무엇입니까?

PATH는 디렉토리가 실행되는 경우에만 bash와 csh에서 다르게 작동합니까?

fread ()는 다른 엔디안 시스템에서 다르게 작동합니까?

Entity Framework는 WHERE의 단계 시퀀스에 대해 동일한 테이블을 쿼리합니다.

이미 사용 된 Linq 쿼리는 Enity Framework의 다른 클래스에서 작동하지 않습니다.

PHP에서 SQL 쿼리 실행이 작동하지 않지만 쿼리는 phpmyadmin에서 작동합니다.

'this'는 브라우저와 노드 환경에서 다르게 작동합니다.

Sum () Entity Framework 쿼리에서 null을 반환합니다.

SQL 스크립트는 DB 호스트에서 실행되는지 다른 호스트에서 실행되는지에 따라 다르게 작동합니다.

.Net Core XSLT 변환에서 "잘못된 XML 문자"예외가 발생합니다. 그러나 .Net Framework에서는 잘 작동합니다.

출시 된 앱은 동일한 기기에서 디버그 바이너리와 다르게 작동합니다.

Entity Framework Core linq 쿼리가 InvalidCastException을 반환합니다.

C sscanf (fscanf)는 행에서 행과 다르게 작동합니다.

twoSum 함수는 다른 배열 입력에서 다르게 작동합니다.

Entity Framework Include ()가 복잡한 쿼리 내에서 작동하지 않습니다.

Entity Framework Core 2.0은 PK를 반환하지 않는 저장 프로 시저를 실행합니다.

Unity 게임 Sqlite 데이터베이스는 Android 장치에서 실행할 때 다르게 작동합니다.

다른 시스템에서 다르게 작동하는 Java AffineTransform