Я использую JPA (Hibernate v4.1.7), Spring Data (v1.4.1) и Query DSL (v3.2.3) для построения моего уровня DAO в базе данных Postgres.
Но сгенерированный SQL для запросов не оптимален для фильтрации по отношению @ElementCollection (аналогичная проблема существует с отношением @OneToMany)
У меня есть сущность:
@Entity
@Table(name = "doc_documents")
public class Document {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ElementCollection(fetch = FetchType.LAZY)
@CollectionTable(name = "doc_document_titles",
joinColumns =
@JoinColumn(name = "document_id"))
@Column(name = "title")
private List<String> titles = new ArrayList<>();
….
)
И интерфейс репозитория:
public interface DocumentRepo
extends JpaRepository <Document, Long>,
QueryDslPredicateExecutor<Document> {
}
Когда я выполняю свой запрос:
Predicate crit = qDoc.titles.any().eq("x");
docRepo.findAll(crit);
Этот SQL выполняется:
select
document0_.id as id10_
from
doc_documents document0_
where
exists (
select
1
from
doc_documents document1_
inner join
doc_titles title2_
on document1_.id= title2_.document_id
where
document1_.id=document0_.id
and locthesaur2_.title = ?
)
Но я думаю, что оптимальный SQL для этого запроса должен быть без дополнительного внутреннего соединения:
select
document0_.id as id10_
from
doc_documents document0_
where
exists (
select
1
from
doc_titles title2_
where
title2_.document_id=document0_.id
and title2.title= ?
)
Дополнительное внутреннее соединение серьезно портит производительность. Можно ли указать QueryDSL для генерации другого запроса, или, может быть, я просто делаю что-то не так?
Проблема производительности жизненно важна для моего приложения, поэтому без этой оптимизации я не могу использовать QueryDSL для запросов к базе данных (у меня гораздо более сложный домен, чем я показал здесь).