Hibernate の JPA 実装を使用していますが、フェッチされるエンティティごとに複数の SQL クエリが発行されるため、パフォーマンスが低下しています。結合された JPA クエリを使用すると、SQL クエリが 1 つだけ生成されますが、行が null 関係になることがわかりません。
例として、次の単純なスキーマを考えてみましょう。個人はある住所に住んでおり、会社に雇用されています。住所と雇用主はどちらもオプションであるため、null にすることができます。
@Entity
public class Person {
public name;
@ManyToOne
@Column(nullable=true)
public Address address
@ManyToOne
@Column(nullable=true)
public Company employer
}
@Entity
public class Address {
address attributes ...
}
@Entity
public class Company {
company attributes ...
}
上記には示されていませんが、各 JPA エンティティには何らかの ID (キー) があります。
@Id
public Integer id;
私が見ている問題は、Person に対する 1 つの JPA クエリが、データベースに対して複数の SQL クエリを生成することです。たとえば、次の JPA クエリ:
select p from Person p where ...
SQL クエリの結果:
select ... from Person where ...
また、取得した人物ごとに次の SQL クエリのペアも使用します。
select ... from Address a where a.id=xxx
select ... from Company c where c.id=yyy
これはパフォーマンスに大きな影響を与えます。クエリの結果セットが 1000 人の場合、1+1000+1000=2001 の SQL クエリが生成されます。
そこで、強制的に参加させて JPA クエリを最適化しようとしました。
select p from Person p join p.address a join p.employer e where ...
また:
select p, a, e from Person p join p.address a join p.employer e where ...
これにより、多数の結合を含む 1 つの SQL クエリが生成されます。問題は、住所または雇用主が null の場合、結合されたクエリでそれが見つからないことです。
そのため、遅い結合のないクエリを使用するか、行を取得しない高速の結合クエリを使用すると関係が null になります。ここで何かが欠けているに違いありません。確かに、高速で完全なクエリを実行する方法はあります。