私のコードは次のようになります:
final CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
final TypedQuery<ObjectTO> createQuery = criteriaBuilder.createQuery(ObjectTO.class);
...
// Logic to create search query
...
// On this line performance is very low. Takes around 200 seconds for 3000 records.
final List<ObjectTO> inhibits = createQuery.getResultList();
生成された SQL (select 句で列を減らした例) は次のようになります。
SELECT t1.COL1 ,
t1.COL2 ,
t1.COL3 ,
t2.COL1 ,
t2.COL2 ,
t3.COL2
FROM Table1 t1
INNER JOIN Table2 t2,
ON t1.COL1 = t2.COL1
LEFT OUTER JOIN Table3 t3
ON t1.COL1 = t3.COL1
WHERE (t1.COL2 LIKE 'test')
AND ( t1.COL3 >= SYSDATE
OR t1.COL3 = to_Date('1901.01.01 00:00:00', 'yyyy-mm-dd HH24:mi:ss') )
ORDER BY t1.COL1 ASC ,
t1.COL3 ASC ,
t2.COL2 ASC;
同じクエリを SQL 開発者で実行すると、約 0.3 秒かかります。java.sql.Statement.executeQuery() を使用して同じクエリを実行すると、データベースからデータを取得するのに約 0.4 秒かかることに注意してください。データベースは Oracle 11g です。JDK のバージョンは 1.7.0_51 です。
Table1 の JPA エンティティは次のようになります。
@Entity
@Table(name = "Table1")
public class Table1 implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "COL1", insertable = false, updatable = false)
private String col1;
@Column(name = "COL3", insertable = false, updatable = false)
private Timestamp col3;
@Column(name = "COL2")
private String col2;
@OneToMany(mappedBy = "col1", cascade = CascadeType.REFRESH, fetch = FetchType.EAGER)
private Set<Table2> table2;
@OneToMany(mappedBy = "col1", cascade = CascadeType.REFRESH, fetch = FetchType.EAGER)
private Set<Table3> table3;
...
...
}
このシナリオでパフォーマンスを向上させるためにどこから始めればよいかについてのヒントを教えてください。さらに情報が必要な場合はお知らせください。