2012-09-06 2 views
2

NHibernate 3.3 및 Firebird 2.5.1 성능 문제가 있습니다. ASP.NET MVC와 로컬 (!) 파이어 버드 데이터베이스를 사용하여 아주 간단한 예제를 만들었습니다. 그러나 다음 코드는 실행에 약 1 초가 걸립니다.NHibernate 및 Firebird 성능 문제

 var startTickCountWrite = Environment.TickCount; 

     IRepository<Project> repository = facade.ProjectRepository(null); 
     for (int i = 1; i <= 250; ++i) 
     { 
      var myProject = new Project { ProjectId = i }; 
      repository.Insert(myProject); 
     } 
     repository.Commit(); 

     var endTickCountWrite = Environment.TickCount; 

for 루프 내부에 commit()을 삽입하면 약 5 초가 걸립니다!

뒤에 저장소 및 외관은 특별한 것이 아닙니다. 프로젝트를 ISession.Forsert로 전달합니다.

프로젝트에는 속성으로 ID와 ProjectID 만 있습니다.

아무도 나에게 무슨 일이 잘못되고 있다고 말할 수 있습니까?

감사합니다, 안드레아스 1 초

+2

그래서 1 초 안에 알 수없는 하드웨어/메모리 구성으로 오픈 소스 데이터베이스에 250 개의 삽입을하고 있는데 이것이 좋지 않다고 생각하십니까? –

+0

_When_ DBMS에 연결하고 있습니까? 아마도 실제로 필요한 때까지 연결이 설정되지 않았으므로이 1 초의 대부분은 DBMS에 연결하는 데 소비 될 수 있습니다. Commit in loop에 관해서는, 이것은 꽤 기대됩니다 - 당신은 내구성 가격을 지불하고 있습니다. 트랜잭션은 ACID 일 필요가 있지만 트랜잭션의 끝에서만 "내구성"을 적용해야합니다. 따라서 디스크에 대한 물리적 입출력은 분명한 SQL 문 실행 후에 연기 될 수 있으며 트랜잭션이 다른 명령문을 처리하는 동안 백그라운드에서 실제로 수행 될 수 있습니다. 귀하의 거래가 너무 세분화되어 있다면 당신은 그것을 물리 칠 수 있습니다. –

답변

1

250 개체는 놀랍게도 느린 소리가 나지 않는다. 성능을 평가하기 위해 Firebird에 대해 동일한 양의 SQL을 직접 실행하는 데 얼마의 시간이 걸리는지 비교해 보는 것이 좋습니다.

어떤 상황에서는 NHibernate가 INSERT 문을 일괄 처리 할 수 ​​있지만 Firebird에서 작동하는지 여부는 알 수 없습니다. http://nhibernate.info/doc/nh/en/index.html#performance-batch-updates 동일성 확인 프로그램을 선택하면 영향을 미칠 수 있습니다. 일부 생성자는 Hibernate로 하여금 즉시 INSERT 문을 실행하도록 강제한다. 이것은 일괄 처리의 사용을 방해 할 것이다. IRepository.Insert()는 컬렉션 인터페이스를 모방하기 때문에 일반적으로 Add()입니다. (컬렉션에 삽입하면 일반적으로 인덱스를 사용합니다.) 매개 변수는 당연히 여기에 관련이 없습니다). 또한 Commit()은 일반적으로 저장소와 관련하여 여러 개의 저장소 인스턴스가 관련되어 있으므로 동일한 트랜잭션과 세션을 공유하므로 저장소에서 비효율적 인 것처럼 보입니다.

정확한 시간 측정을 위해 System.Diagnostics에서 Stopwatch를 사용할 수 있으므로 직접 값을 변환 할 필요가 없습니다.

+0

답변 해 주셔서 감사합니다. 처음에는 250 개의 인서트에 약 1 초의 충격을 받았습니다. 하지만 몇 가지 다른 테스트를 통해 괜찮은 것 같습니다. 디자인에 대한 귀하의 힌트를 주셔서 감사합니다. – Andreas