2010-07-27 3 views
12

현재 웹 응용 프로그램의 저장소 인 db4o 사용에 대한 조사를하고 있습니다. 나는 db4o가 얼마나 쉽게 작동 하는지를 매우 기쁘게 생각합니다. 그래서 EF4 Code First로 작업하는 방법이 db4o로 작업하는 것과 매우 비슷하기 때문에 내가 좋아하는 Code First 접근법에 대해 읽었을 때 도메인 객체 (POCO 's)를 만들고 db4o에서 던져 버리고 결코 되돌아 보지 마십시오.왜 EF4 코드가 먼저 객체를 저장할 때 느린가요?

하지만 성능 비교를했을 때 EF 4는 매우 느립니다. 그리고 그 이유를 알 수 없었습니다.

내가 다음 엔터티 사용

public class Recipe { private List _RecipePreparations; public int ID { get; set; } public String Name { get; set; } public String Description { get; set; } public List Tags { get; set; } public ICollection Preparations { get { return _RecipePreparations.AsReadOnly(); } }

public void AddPreparation(RecipePreparation preparation) 
    { 
     this._RecipePreparations.Add(preparation); 
    } 
} 

공용 클래스 RecipePreparation { 공공 문자열 이름을 {얻을; 세트; } 공용 문자열 설명 {get; 세트; } public int Rating {get; 세트; } 공개 목록 Steps {get; 세트; } 공개 목록 태그 {get; 세트; } public int ID {get; 세트; } }

나는 조리법을 새로운 성능을 테스트하고, 50.000 RecipePrepations를 추가합니다. 그럼 난과 같이 db4o는에 객체를 저장 :

cookRecipes.Recipes.Add(recipe1); 
cookRecipes.SaveChanges(); 
:

IObjectContainer db = Db4oEmbedded.OpenFile(Db4oEmbedded.NewConfiguration(), @"RecipeDB.db4o"); 
db.Store(recipe1); 
db.Close(); 

이이 같은 약 13.000 (MS) (로컬 익스프레스,) 내가 SQL Server 2008의 EF4로 물건을 저장

소요

그리고 그게 200.000 (ms) 걸립니다

이제 어떻게 지구상에서 db4o 15 (!!!) 번 EF4/SQL 빠른 무엇입니까? EF4 용 비밀 터보 버튼이 누락 되었습니까? 나는 심지어 db4o가 더 빨라질 수 있다고 생각합니까? 데이터베이스 파일을 초기화하지 않으므로 동적으로 커지게 만듭니다.

+1

내 생각 엔이 많은 단일 삽입 명령문의 오버 헤드 차이의 가장 큰 부분입니다 실행되는 것입니다. 그 오버 헤드를 줄이기 위해 EF4에 insert 문을 결합하도록 지시하는 방법이 있습니까? –

+0

@Lasse : 예, 있습니다. EF는 작업 단위 패턴을 상자 밖으로 구현합니다. 제 답변을 참조하십시오. –

+1

Visual Studio에서 프로파일 링을 수행했습니다. 그리고 cookRecipes.Recipes.Add (recipe1)는 총 저장 시간의 약 65 %를 저장하고 SaveChanges는 약 35 %를 소비합니다 (duh ...;)). – Saab

답변

3

SaveChanges()안에 루프를 호출 했습니까? 천천히하는 것이 당연합니다!

foreach(var recipe in The500000Recipes) 
{ 
    cookRecipes.Recipes.Add(recipe); 
} 
cookRecipes.SaveChanges(); 

EF 당신은 당신이 원하는 모든 변경을 할 것으로 기대하고 일단 SaveChanges전화 :이 일을보십시오. 그런 식으로 데이터베이스 통신을 최적화하고 sql은 열린 상태와 저장 상태 사이의 변경을 수행하고 실행 취소 한 모든 변경 사항은 무시합니다. 예를 들어 레코드 50,000 개를 추가 한 다음 그 중 절반을 제거한 다음 SaveChanges을 입력하면 데이터베이스에 25 000 개의 레코드 만 추가됩니다.

+0

루프가 db4o 또는 EF4/SQL에 데이터가 저장되기 전에있었습니다. 그래서 나는 처음으로 Recipe를 시작합니다. 그리고 난 루프에서 RecipePreparations를 추가합니다. 이제는 50.000의 RecipePreparation이 첨부 된 Recipe가 있습니다. 그런 다음 db4o 또는 EF4/SQL에 저장합니다. 그래서 db4o에 하나의 db.store (recipe1)가 있고 EF4에는 하나의 cookRecipes.Recipes.Add (recipe1); cookRecipes.SaveChanges()가 있습니다. – Saab

+0

DB4O가 로컬 시스템의 파일에 저장 중입니까? 그리고 EF4는 데이터베이스 연결을 로컬에서 열어야합니다. 연결은 일반적으로 열려 있으므로 발사 당 비용입니다. 삽입을위한 타이밍 루프가 방정식에서 그 연결 시간을 빼내기 전에 데이터베이스의 첫 번째 항목을 얻기 위해 선을 추가하십시오. – DamienG

1

EF는 많은 항목에서 뛰어나지 만 대량로드는 그 중 하나가 아닙니다. . 고성능 대량로드를 원할 경우 DB 서버를 통해 직접 수행하면 ORM보다 빠릅니다. 앱의 유일한 성능 제약이 대량로드 인 경우 EF를 사용하지 않아야합니다.

+0

그렇다면 EF 사용에 의문이 생깁니다. 당신은 응용 프로그램이 매우 복잡한 모델 (도메인 개체)에 의존하고 있다면 나는 dbo와 같은 oo 데이터베이스를 선호 할 것입니다. 그러나 데이터가 주로 표 형식 인 경우 전통적인 관계형 데이터베이스를 사용하고 선택적으로 EF와 같은 OR/M을 사용합니다. 하지만 대량로드/삽입/업데이트를 수행 할 때 EF가 실패한다고 말한 것입니다. 그래서 내가 두려웠 던 것은 실제로 사실입니다. EF4는 매우 가벼운 데이터베이스 작업을 수행하는 경우에만 옵션이며, 관계형 데이터베이스를 사용해야합니다. – Saab

+1

다시 EF뿐 아니라 * 모든 * ORM은 DB 서버의 대량로드 기능보다 느립니다. EF는 대량 삽입을 지원하는 ORM보다 느릴 수 있지만 DB 서버 전용 대량로드 기능에 사용되는 스트리밍 API만큼 빠르지는 않습니다. 일괄로드는 대부분의 앱에서 가장 중요한 부분이지만, 빵과 버터라면 ORM보다 SSIS와 같은 것을 사용하는 것이 좋습니다. –

+0

대부분의 OR/M은 대량로드에 비해 속도가 느리다는 것에 동의합니다. 하지만 OR/M은 데이터베이스의 대량로드 기능을 사용할 수 없다는 것에 동의해야합니다. 이 코드는 매우 쉽게 생성 할 수 있습니다. 하지만 EF4 Code First에 문제가 있다고 생각합니다. 레시피 엔티티를 dbContext에 추가하는 데는 (130 초) 많은 시간이 걸립니다. 데이터베이스 (dbContext.Recipes.SaveChanges)에 저장하는 것은 속도 악마가 아니며 50.001 행의 경우 70 초입니다. 이것은 50.000/70 = 714 행/s로 변환됩니다. – Saab

1

다른 답변에 추가하면됩니다. db4o는 일반적으로 프로세스 내에서 실행되지만 EF는 out-of-process (SQL) 데이터베이스를 추상화합니다. 그러나 db4o는 기본적으로 단일 스레드입니다.따라서 하나의 요청으로이 예제를 사용하는 것이 더 빠르지 만 SQL은 기본 db4o 데이터베이스 설정보다 동시성 (여러 쿼리, 다중 사용자)을 훨씬 잘 처리합니다.

관련 문제