2012-09-26 2 views
6

Websphere Application Server 7을 buildin OpenJPA 1.2.3 및 Oracle 데이터베이스와 함께 사용하고 있습니다. 계약을 검색 할 수성능 OpenJPA 쿼리 (3000+ 레코드)가 느림

@NamedNativeQuery(name=Contract.GIVE_ALL_CONTRACTS, 
     query="SELECT number, name \n" + 
      "FROM contracts \n" + 
      "WHERE startdate <= ?1 \n" + 
      "AND enddate > ?1", 
      resultSetMapping = Contract.GIVE_ALL_CONTRACTS_MAPPING) 
    @SqlResultSetMapping(name = Contract.GIVE_ALL_CONTRACTS_MAPPING, 
     entities = { @EntityResult(entityClass = Contract.class, fields = { 
      @FieldResult(name = "number", column = "number"), 
      @FieldResult(name = "name", column = "name") 
     }) 
    }) 
    @Entity 
    public class Contract { 
     public static final String GIVE_ALL_CONTRACTS = "Contract.giveAllContracts"; 
     public static final String GIVE_ALL_CONTRACTS_MAPPING = "Contract.giveAllContractsMapping"; 

     @Id 
     private Integer number; 
     private String name; 

     public Integer getNumber() { 
     return number; 
     } 
     public String getName() { 
     return name; 
     } 
    } 

그리고 다음 코드 :

Query query = entityManager.createNamedQuery(Contract.GIVE_ALL_CONTRACTS); 
query.setParameter(1, referenceDate); 

List contracts = query.getResultList(); 
entityManager.clear(); 

return contracts; 

검색된 계약은 웹 서비스에 전달 나는 다음과 같은 개체가 있습니다.

Oracle 개발자에서이 쿼리를 실행하면 3608 개의 레코드가 0.35 초 걸립니다. query.getResultList() 호출에 약 4 초가 걸립니다.

엔티티 구성자의 로그 작성자는 동일한 타임 스탬프로 생성 된 약 10-20 개의 엔티티가 기록됩니다. 그러면 0,015 초가 걸립니다. 나는 OpenJPA 물건을 추측한다.

OpenJPA의 속도를 높일 방법이 있습니까? 아니면 유일한 솔루션 캐싱입니까?

+1

프로필러를 사용하는 것이 좋습니다. – user1516873

답변

3

개체 생성시 성능이 크게 떨어질 수 있습니다. 서버에서 코드를 실행하는 동안 데이터베이스를 쿼리 할뿐만 아니라 메모리를 할당하고 각 행에 대해 새 Contract 개체를 만듭니다. 확장 된 힙 또는 가비지 수집주기는 관찰 한 유휴 기간에 포함될 수 있습니다.

large results sets을 처리하는 방법에 대한 OpenJPA 문서를 보자.

+1

openjpa.FetchBatchSize가 정말 중요합니다. 오라클에서는 단지 10 일뿐입니다. –

+0

다음 코드를 추가했습니다 :'OpenJPAQuery kq = OpenJPAPersistence.cast (query); JDBCFetchPlan fetch = (JDBCFetchPlan) kq.getFetchPlan(); fetch.setFetchBatchSize (100); fetch.setResultSetType (ResultSetType.SCROLL_INSENSITIVE); fetch.setFetchDirection (FetchDirection.FORWARD); fetch.setLRSSizeAlgorithm (LRSSizeAlgorithm.LAST);'웹 서비스 호출을하면 +/- 600ms의 결과가 반환됩니다. 이것은 정말 빠릅니다! 이 위대한 팁을 주셔서 감사합니다 –

+0

당신은 또한 사용할 수 있습니다 : 'query.setHint ("openjpa.FetchPlan.FetchBatchSize", "100"); query.setHint ("openjpa.FetchPlan.ResultSetType", "SCROLL_INSENSITIVE"); query.setHint ("openjpa.FetchPlan.LRSSizeAlgorithm", "LAST"); ' –

0

VisualVM을 다운로드하고 관련 패키지에 대한 프로파일 링을 설정하는 것이 좋습니다. VisualVM은 이론적으로는 0.35 초까지 합계되는 여러 가지 방법으로 보낸 시간을 보여줄 수 있습니다. 코드, OpenJPA 및 네트워크 IO 사이의 총 시간 분포를 분석 할 수 있습니다. 그러면 병목 현상을 식별하는 데 도움이됩니다.

+0

네트워크 오버 헤드가 아닌 한. 아마 그럴거야. –

+0

@Natan Cox Network를 완벽하게 볼 수 있으며 프로파일 링 된 패키지에 java.io. *를 포함하면됩니다. 데이터베이스 통신은 일종의 io.read로 보일 것입니다. 정확한 메소드 이름을 기억하지 못합니다. – jabal