2012-09-26 3 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 занимает около 0,35 секунды для 3608 записей. Вызов query.getResultList() занимает около 4 секунд.

С регистратором в constuctor объекта он регистрирует, что существует около 10-20 объектов, созданных с одинаковой меткой времени. Затем 0,015 секунды он делает что-то еще. Я думаю, что OpenJPA.

Есть ли способ ускорить OpenJPA? Или это единственное решение для кеширования?

+1

Предлагаю вам использовать профайлер. – user1516873

ответ

3

Создание объекта может иметь свою долю в достижении производительности. При запуске вашего кода на сервере вы не только запрашиваете базу данных, но также выделяете память и создаете новый объект Контракта для каждой строки. Расширяющийся цикл кучи или мусора может рассчитывать на периоды простоя, которые вы наблюдали.

Я предлагаю вам ознакомиться с документацией OpenJPA о том, как обрабатывать large results sets.

+1

openjpa.FetchBatchSize действительно важно. В Oracle это (только быть?) Только 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); 'Когда я звоню в webservice, он возвращает результат в +/- 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

Смежные вопросы