1

EF 쿼리 웹 응용 프로그램을 통해 실행하는 일부 성능 측정 문제가 있고 Profiler를 실행하면 T-SQL이 SQL 쿼리 창으로 직접 생성되었습니다. 그것이 실행 주위 221'095 MS했다 것을 알 수엔티티 프레임 워크 및 SQL Server 프로필러

IEnumerable<application> _entityList = context.applications 
        .Include(context.indb_generalInfo.EntitySet.Name) 
        .Include(context.setup_budget.EntitySet.Name) 
        .Include(context.setup_committee.EntitySet.Name) 
        .Include(context.setup_fund.EntitySet.Name) 
        .Include(context.setup_appStatus.EntitySet.Name) 
        .Include(context.appSancAdvices.EntitySet.Name) 
        .Where(e => e.indb_generalInfo != null); 

       if (isIFL != null) 
        _entityList = _entityList.Where(e => e.app_isIFL == isIFL); 

       int _entityCount = _entityList.Count(); // hits the database server at this line 

EF 쿼리 위를 추적하는 동안 SQL 프로파일 러 : 다음

은 웹 응용 프로그램을 통해 실행 내 EF의 쿼리입니다. (30,000+, 11,000+를 갖는 indb_generalInfo 및 30,000+ 레코드를 갖는 appSancAdvices를 갖는 애플리케이션 테이블).

그러나 Profiler에서 T-SQL을 복사하고 쿼리 창에서 직접 실행하면 4'000 ms 만 사용됩니다.

왜 그렇습니까?

+0

동일한 쿼리를 여러 번 실행 해 보셨습니까? Entity Framework는 여전히 해당 쿼리를 생성해야하지만 이후 요청을 위해 캐시됩니다. 또한,'Count()'를하고 있다면, 열심히 로딩 할 필요가 없다. –

+0

예 이전에 시도 했었습니다. 그러나 문제는 @Arnold가 정확히 알게 된 것이 었습니다. –

답변

4

이 쿼리의 독은 첫 번째 단어는 IEnumerable<application>입니다. var (즉 IQueryable)으로 바꾸면 검색어는 마지막으로 Count()까지 SQL로 변환됩니다. 전송 된 데이터의 양이 거의 없기 때문에 시간이 많이 걸릴 것입니다.

또한 bobek이 이미 언급했듯이 context.applications 수만 있으므로 Include이 필요하지 않습니다.

그 외에도 항상 Entity Framework와 같은 ORM을 사용하는 오버 헤드가 있습니다.

+0

IQueryable의 EF 구현은 지연된 실행을 사용하므로 Count가 호출 될 때까지 쿼리가 sql로 변환되지 않습니다. 또한 AsEnumerable() 또는 ToList()를 호출하여 변환을 강제 수행 할 수 있으며 이는 sql로 변환 할 수없는 필터를 사용할 때 유용합니다. 그러나 변수 선언을 단순히 IEnumerable에서 IQueryable로 변경하면 AFAIK는 아무런 효과가 없습니다. – Colin

+0

@ 콜린 것입니다. IEnumerable 을 사용하면 첫 번째 명령문 다음에 'AsEnumerable'을 호출하는 것과 같은 효과가 있으므로 나머지 LINQ 명령문이 적용되기 전에 레코드를 강제로 메모리로 가져와 강제 실행합니다. '백작. –

+1

변수 선언을 var에서 IEnumerable <>로 변경하고 EF로 전달 된 경우 실패한 쿼리에서 AsEnumerable() 호출을 제거하여이 코드를 테스트했습니다. 그리고 @Gert가 맞는지 확인할 수 있습니다. 나는 교정되었고 나는 새로운 것을 오늘 배웠다. 따라서 "이 줄에있는 데이터베이스 서버에 도달했습니다"라는 질문의 주석은 정확하지 않으며 SQL 프로파일 러에서 볼 수있는 쿼리에서 분명해야합니다. 결과는 정수가 아닌 결과 집합이됩니다 – Colin

0

EF가 먼저 코드를 TSQL로 변환해야하므로 비용이 많이 들기 때문입니다. 이 링크를 보시려면 여기를보십시오 : http://peterkellner.net/2009/05/06/linq-to-sql-slow-performance-compilequery-critical/ LINQ를 컴파일하고 속도에 도움을 줄 것입니다. 또한이 쿼리를 위해 많은 테이블이 정말로 필요한가요? 어쩌면 당신은 그것을 걸러 낼 수있는 방법을 생각하고 필요한 것만 빼낼 수 있을까요?

+0

ef5는 기본적으로 캐시되어야합니다. –

0

EF는 확실히 성능 측면에서 비용이 듭니다. 또한 복잡한 TSQL에 대해 storedprocs를 사용할 수있는 유연성을 제공합니다. 그러나 내 생각에 그것은 당신의 최후의 수단이되어야합니다.

0

당신이 재 경기와 EF에 관심이있는 경우. 그러나 http://msdn.microsoft.com/en-us/data/hh949853.aspx

... SQL 프로파일 러의

EF 쿼리는 그것이 실행 주위 221'095 MS 걸린 알 수있다. 다음

..

사본 SQL에서 온 프로파일에서 T-SQL과 쿼리 창

에서 직접 실행은 무관하다. Q1에 x 밀리 초가 걸렸습니다. SQL 프로파일 러 정보 기반 정확히 동일한 쿼리 Q1 '은 SQL 프로파일 러를 기반으로합니다. 이것은 SQL의 출처가 문제가 아니라는 것을 의미합니다. 환경 문제가 관련되어 있음을 의미합니다.

SQL 서버는 많은 데이터 페이지를 버퍼링했으며 두 번째 동일한 요청을 훨씬 잘 처리 할 수 ​​있습니다.

관련 문제