2013-08-06 2 views
1

내 ASP MVC 응용 프로그램의 EF5 DbContext 모델에 대한 일부 쿼리에서 성능 문제가 발생합니다.Entity Framework 5 쿼리가 느리게 실행됩니다.

쿼리는 많은 탐색 그래프의 여러 수준, 예를 이상 포함되어 있습니다

Context.Cars 
.Include(c=>c.Model.Maker) 
.Include(c=>c.CarOwners.Select(co=>co.Owner)) 
.Include(c=>c.Navigation1) 
.Include(c=>c.Navigation2) 
.Include(c=>c.Navigation3) 
.ToList(); 

나는 그것을 실행하는 데 약 10 초가 걸립니다 쿼리를 실행하지만, 처음 나는 페이지를 두 번째를 새로 고칠 때 실행에 걸리는 시간은 1 초 미만입니다.

Visual Studio의 성능 분석 도구를 실행하여 문제가있는 곳을 확인했으며 GetExecutionPlan() 메서드가 대부분 시간을 소비하고있는 것 같습니다.

쿼리가 두 번째로 실행 된 후 (페이지 새로 고침) 쿼리가 실제로 빠르기 (초 미만)로 실행 된 후 계획이 캐시되고있는 것 같습니다.

쿼리가 실제로 복잡하기 때문에 fistp 페이지로드의 성능이 제한된다는 것을 알고 있습니다 (DB로 덤프 된 SQL 코드는 약 4k 라인입니다). 그러나 문제는 내가 1 시간 내에 페이지로 돌아 오면 질의가 다시 느려진다는 것입니다. 실행 계획 캐시가 어떻게 든 지워진 것 같습니다. IIS 설정을 검사하고 모든 응용 프로그램 풀 재활용 설정이 해제되어 있습니다.

그냥 명확하게, 나는 내 쿼리를 최적화하는 방법을 찾고 있지 않다. 내 쿼리가 이상하게 작동하는 이유가 궁금하다. 먼저 느린로드, 두 번째로드가 빠르며 한 시간 후에 다시로드가 느려지는지 궁금하다.

아이디어가 있으십니까?

+0

네, 분명히 일종의 캐싱이 있습니다. 그러나 메커니즘에 대해 궁금해하고 있으며 시간이 지나면 새 실행 계획을 계산하기 시작하는 이유는 무엇입니까? –

답변

1

EntityFramework.dll의 v5.0.0에서 내부 클래스 System.Data.Common.QueryCache.QueryCacheManager있다 (dotPeek이 구조에. 나는 V6에서 제거되었을 수 있습니다. Codeplex에 소스의 클래스를 찾을 수 없습니다) .0은 말하지만 조금 복잡합니다.

여기에 대한 내용은 다음과 같습니다. 계획이 캐시에 추가되면 타이머가 시작됩니다 (아직 실행 중이 아닌 경우). 타이머는 60000 밀리 초 (1 분)마다 캐시 스윕을 트리거하고 캐싱 된 계획이 800 개 이상 있으면 실제로 캐시가 스윕됩니다. 마지막 스윕 이후에 재사용되지 않은 계획은 캐시에서 제거됩니다. 캐시의 계획 수가 800 개 미만이면 스윕을 건너 뛰고 타이머가 중지됩니다.

다음은 내가 잘 모르겠다는 것입니다 : 캐시 스윕의 일부입니다. 꽤 이해가 가지 않지만, 영리하다고 생각합니다. 산법에 따라 캐시를 유지하는 것이 더 힘들어지는 알고리즘처럼 보이지만, 각 스윕의 양을 늘려 적중 횟수를 오른쪽으로 비트 단위로 이동하면 더 많은 스윕이 발생합니다. 첫 번째 및 두 번째 스윕에서 1, 2, 4, 16까지 이동합니다. 이유는 무엇인지 확실하지 않아서 계획에 필요한 횟수를 정확히 파악하는 데 어려움을 겪고 있습니다. 캐시에 5 분 이상 머무르는 데 사용됩니다. 나는 누군가가 1) 정확히 무엇을하고 있는지에 대한 더 많은 정보를 줄 수 있고, 2) 이것을하기위한 이유가 무엇인지를 고맙게 생각한다.

어쨌든 계획이 영원히 캐싱되지 않는 이유입니다.

관련 문제