2012-09-26 10 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; 

取り出さ契約がWebサービスに渡され、私は、次のエンティティを持っています。

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); '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

関連する問題