Я использую реализацию JPA в Hibernate и наблюдаю низкую производительность, так как для каждой извлекаемой сущности выдается несколько SQL-запросов. Если я использую объединенный запрос JPA, он генерирует только один запрос SQL, но не находит строк, которые будут иметь нулевое отношение.
Пример, рассмотрим эту простую схему. Человек живет по адресу и работает в компании. И адрес, и работодатель являются необязательными и поэтому могут быть нулевыми.
@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
public Integer id;
Проблема, с которой я сталкиваюсь, состоит в том, что один запрос JPA для Person приводит к нескольким запросам 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 ...
В результате получается один SQL-запрос с несколькими объединениями. Проблема в том, что если адрес или работодатель не заданы, объединенный запрос их не найдет.
Так что мне остается либо использовать медленный запрос без объединения, либо быстро соединяющийся запрос, который не извлекает строки, будет иметь нулевые отношения. Я должен что-то здесь упустить. Конечно, есть способ для быстрого и полного запроса.