2013-03-19 2 views
2

설정 변경 ~ 저장하는 40 ~ 60 초에서 취SaveChanges를 8000 문맥

  • 엔티티 프레임 워크 4 게으른 로딩 활성화 (모델 첫째, 테이블 당 계층 구조).
  • 테이블의 수는 약 40 개 (테이블에는 15-20 개 이상의 필드가 없습니다).
  • SQL Server Express 2008 (r2가 아님).
  • 데이터베이스 트리거 또는 기타 이와 같은 것들은 존재하지 않습니다. 이는 저장 용으로 만 사용됩니다. 모든 논리가 코드에 있습니다.
  • 현재 데이터베이스 크기는 약 2GB입니다.
  • (기본 키의 GUID하고 Guid.NewGuid() 통해 코드 생성된다 -이 문제 경우)
  • (복잡한 객체 그래프를 생성) 복잡한 연산 결과를 저장하는 40 내지 60 초 (SaveChanges 의해 반환 번호가 어디서나 얻어 약 8000 - 주로 추가 된 객체와 일부 수정 됨).
  • 빈 (또는 거의 비어있는) 데이터베이스에서 동일한 작업 결과를 저장하면 대개 같은 컴퓨터에서 약 1 초가 걸립니다.

이 문제에 영향을주는 변수는 데이터베이스 크기뿐입니다. 그러나 나는 단지 Context.SaveChages() 전화를 측정하고 있기 때문에 (이 문제에 영향을 미치지 않아야 할 이상한 부진한 쿼리가 있더라도).

이 작업이 왜 이렇게 오래 지속될 수 있는지에 대한 제안 사항에 감사드립니다.

Stopwatch sw = Stopwatch.StartNew(); 
int count = objectContext.SaveChanges(); // this method is not overridden 
Debug.Write(sw.ElapsedMilliseconds); // prints out 40000 - 60000 ms 
Debug.Write(count); // I am testing with exactly the same operation and the 
        // result always gives the same count for it (8460) 

: -

는 UPDATE는

1은 그냥 명확하게 실행 40-60초 소요되는 코드를 (이것은이 긴 경우에만 DB 크기가 2GB 주위 때 소요) 빈 DB를 사용하는 동일한 작업에는 1000 밀리 초가 걸립니다 (여전히 8460을 제공함). 따라서 질문은 - 데이터베이스 크기가 SaveChanges()에 어떻게 영향을 미칠 수 있습니까? 있다 3

Method: static SNINativeMethodWrapper.SNIReadSync 
Called: 3251 times 
Avg:   10.56 ms 
Max:  264.25 ms 
Min:   0.01 ms 
Total: 34338.51 ms 

업데이트 :

업데이트 2

반환 한 프로파일 러를 실행하면 ("코드의 관점"에서) 주요 병목 현상은 다음과 같은 방법임을 보여줍니다 데이터베이스의 모든 PK 및 FK에 대한 비 클러스터형 인덱스 우리는 랜덤 Guid를 대리 키 (순차가 아닌)로 사용하고 있으므로 조각화는 항상 매우 높은 수준입니다. 나는 모든 DB 인덱스를 재구성 한 직후에 문제의 연산을 테스트하는 것을 시도했지만 (모든 인덱스에 대해 단편화가 2 ~ 3 % 미만 이었지만) 상황을 개선하지는 못했습니다.

또한 문제의 작업 중 하나의 테이블에는 약 4 백만 행이 있습니다 (이 테이블에는 많은 삽입이 있음). SQL 프로파일 러는 해당 테이블에 대한 삽입이 1 ~ 200ms 사이에서 지속될 수 있음을 보여줍니다 ("스파이크"). 다시 한번 말하지만, 색인이 새로 고쳐지면이 변경 사항이 보이지 않는 것 같습니다.

어쨌든 - 시간이 많이 걸리기 때문에 문제는 응용 프로그램의 SQL Server쪽에있는 것 같습니다 (SNIReadSync 메서드). 내가 완전히 무지한 경우에 나를 정정하십시오.

+0

테이블의 기본 키 인덱스를 사용하는 두 번째 쿼리 내부의 루프 여야합니다 ... 아, 코드 또는 데이터베이스 구조를 볼 수 없었기 때문에 추측이었습니다. –

+0

비 순차적 GUID를 사용하면 삽입에 대한 성능이 저하 될 수 있지만 테이블이 상당히 크지 않으면 (예상치로 100 만 개가 넘지 않을 수도 있습니다.) – leppie

+0

@ MarkSchultheiss 실제로 질문을 읽었습니까? 어떤 코드를보고 싶니? 'ObjectContext.SaveChages()'를 반영 했습니까? 그것이 저조한 선이므로 (스톱워치에 따라). 전체 데이터베이스 구조를 게시하는 것은 상당히 복잡하기 때문에 문제가 많습니다 (단지 10-15 개의 테이블을 상상할 수 있습니다). 특히 당신이 알아야 할 것은 무엇입니까? 마지막 두 글 머리표 - 내 문제의 이상한 부분을 확인하십시오. SaveChanges() 실행 시간이 DB 크기가 커지면서 증가하는 이유는 무엇입니까? – Jefim

답변

0

프로파일 러 없이는 추측하기가 어렵지만 기록은 8000 개가 너무 많습니다. 일반적으로 EF 4는 최대 두 개의 개체로 작동합니다. 이 변경 추적이이 시간의 대부분을 차지하는 경우 나는 놀라지 않을 것입니다. EF 5와 6에는 몇 가지 성능 최적화 기능이 있으므로 어떻게 든 추적 된 개체 수를 줄일 수 없다면 실험 해 볼 수 있습니다.

+0

음 ... 다시 말하지만 데이터베이스가 비어있을 때 같은 양의 변경이 실행 되려면 1-2 초가 걸립니다. 데이터베이스가 커지면 많은 시간이 걸립니다. 그리고 그것은 내가 이해하지 못하는 것입니다. 프로파일 러 사용에 대한 요지는 유효하지만, 체크 아웃 할 필요가 있습니다. 아마도 누군가는 데이터베이스 크기와 'SaveChanges'(아마도 알려진 이슈 또는 비슷한 것)를 호출하는 데 걸리는 시간과의 관계에 대해 알고있을 것입니다. – Jefim

+0

@Jefim 데이터베이스 크기와 'SaveChanges'를 호출하는 데 걸리는 시간의 관계는 아마도 EF와 더 관련이 없으며 데이터베이스 설정 방법과 관련이 있습니다. 귀하의 색인은 무엇입니까? 클러스터는 어떤 유형의 인덱스입니까 (클러스터 된/클러스터되지 않은)? 인덱스는 삽입과 관련하여 성능에 다소 큰 영향을 줄 수 있습니다. 비어 있지 않은 데이터베이스에 몇 개의 레코드가 있습니까? – Kittoes0124

+0

모든 테이블에는 대리 Guid PK (클러스터되지 않은 인덱스)가 있고 모든 FK도 클러스터되지 않은 인덱스입니다. 물론 우리가 Guids를 사용한다는 사실은 인덱스 조각화가 항상 끔찍하다는 것을 의미합니다. 연산과 관련된 테이블 중 하나에 4 백만 행이 포함됩니다. 다른 테이블의 행은 상당히 적습니다 (수만 개). 그리고 인덱스 재구성 (DB의 모든 인덱스에 대해 단편화가 2-3 % 이상되지 않는 경우) 후에는 조작 성능이 향상되지 않습니다. – Jefim