2012-09-26 88 views
6

我正在使用带有buildin OpenJPA 1.2.3和Oracle数据库的Websphere Application Server 7。我有以下实体:性能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; 

检索到的合同被传递到web服务。

在Oracle开发人员中执行此查询需要大约0.35秒的3608记录。 对query.getResultList()的调用大约需要4秒钟。

在实体的构造函数中使用记录器时,它会记录约10-20个使用相同时间戳创建的实体。然后0,015秒它做别的事情。我猜OpenJPA的东西。

有没有办法加快OpenJPA?或者是唯一的解决方案缓存?

+1

我建议你使用分析器。 – user1516873

回答

3

对象创建可能会在性能上有所公平。在服务器中运行代码时,不仅要查询数据库,还要分配内存并为每行创建一个新的Contract对象。扩展的堆或垃圾收集周期可能会计算您观察到的空闲时间段。

我建议你浏览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);'当我调用web服务时,它返回一个+/- 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