[c#] EF 4.1에 엔터티를 삽입하는 것이 ObjectContext에 비해 느린 이유는 무엇입니까?

기본적으로 하나의 트랜잭션에 35000 개의 객체를 삽입합니다.

using(var uow = new MyContext()){
  for(int i = 1; i < 35000; i++) {
     var o = new MyObject()...;
     uow.MySet.Add(o);
  }
  uow.SaveChanges();
}

이것은 영원히 걸립니다! 기본 ObjectContext를 사용하면 (를 사용하여 IObjectAdapter) 여전히 느리지 만 약 20 초가 걸립니다. DbSet<>정사각형 시간이 걸리는 선형 검색을 수행하는 것 같습니다 .

이 문제를 본 다른 사람이 있습니까?



답변

Ladislav가 주석에서 이미 언급했듯이 성능을 개선하려면 자동 변경 감지를 비활성화해야합니다.

context.Configuration.AutoDetectChangesEnabled = false;

이 변경 감지는 DbContextAPI 에서 기본적으로 활성화됩니다 .

API DbContext와 다르게 작동 하는 이유 ObjectContext는 자동 변경 감지가 활성화 된 경우 API의 함수보다 DbContextAPI 의 더 많은 함수가 DetectChanges내부적으로 호출 ObjectContext되기 때문입니다.

여기DetectChanges 에서 기본적으로 호출 되는 함수 목록을 찾을 수 있습니다 . 그들은:

  • Add, Attach, Find, Local, 또는 Remove회원에DbSet
  • GetValidationErrors, Entry또는 SaveChanges회원DbContext
  • Entries에 방법DbChangeTracker

특히 귀하가 경험 한 성능 저하의 원인이되는 Add통화 DetectChanges.

이와 대조적으로 ObjectContextAPI는 위에서 언급 한 다른 해당 메서드를 호출 하지 않고 DetectChanges자동으로 호출 합니다 . 이것이의 기본 성능 이 더 빠른 이유 입니다.SaveChangesAddObjectObjectContext

DbContext많은 기능 에서이 기본 자동 변경 감지를 도입 한 이유는 무엇 입니까? 확실하지 않지만, 그것을 비활성화 DetectChanges하고 적절한 지점에서 수동으로 호출하는 것은 고급 으로 간주되고 응용 프로그램에 미묘한 버그를 쉽게 도입 할 수 있으므로 [it]를주의해서 사용하십시오 .


답변

EF 4.3 CodeFirst를 사용한 약간의 경험적 테스트 :

AutoDetectChanges = true : 23 초로 1000 개의 개체 제거

AutoDetectChanges = false로 1000 개의 개체 제거 : 11 초

AutoDetectChanges = true : 21 초로 개체 1000 개 삽입

AutoDetectChanges = false로 개체 1000 개 삽입 : 13 초


답변

.netcore 2.0에서는 다음으로 이동되었습니다.

context.ChangeTracker.AutoDetectChangesEnabled = false;


답변

여기에서 찾은 답변 외에도. 데이터베이스 수준에서 추가하는 것보다 삽입해야하는 작업이 더 많다는 것을 아는 것이 중요합니다. 데이터베이스는 새 공간을 확장 / 할당해야합니다. 그런 다음 최소한 기본 키 인덱스를 업데이트해야합니다. 인덱스는 업데이트 할 때도 업데이트 될 수 있지만 훨씬 덜 일반적입니다. 외래 키가있는 경우 참조 무결성이 유지되는지 확인하기 위해 해당 인덱스도 읽어야합니다. 트리거는 동일한 방식으로 업데이트에 영향을 미칠 수 있지만 역할도 할 수 있습니다.

모든 데이터베이스 작업은 사용자 항목에서 시작된 일일 삽입 활동에서 의미가 있습니다. 그러나 기존 데이터베이스를 업로드하는 중이거나 많은 삽입을 생성하는 프로세스가있는 경우. 끝까지 연기하여 속도를 높이는 방법을 살펴볼 수 있습니다. 일반적으로 삽입하는 동안 인덱스를 비활성화하는 것이 일반적인 방법입니다. 경우에 따라 수행 할 수있는 매우 복잡한 최적화가 있지만 다소 압도적 일 수 있습니다.

일반적으로 삽입은 업데이트보다 오래 걸립니다.


답변