我正在尝试调整由CriteriaQuery生成的SQL请求。
@Entity
@Table(name = "DOCUMENT")
@SequenceGenerator(name = "sequence.generator",sequenceName = "DOCUMENT_SEQ", allocationSize = 1)
public class Document {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequence.generator")
private Long id;
//other data
}
@Entity
@Immutable
@Table(name = "DOCUMENT_VERSION")
public class DocumentVersionRegistry implements Serializable{
@Id
@Getter @Setter
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "DOC_ID")
@Getter @Setter
private Document document;
//other data
}
这是我当前的建造者:
private Specification<Document> getDocumentWithVersions(filterparams){
return new Specification<Document>() {
public Predicate toPredicate(Root<Document> documentPath, CriteriaQuery<?> query, CriteriaBuilder builder){
Subquery<Document> sq = query.subquery(Document.class);
Root<DocumentVersionRegistry> version = sq.from(DocumentVersionRegistry.class);
Predicate predicate = builpredicate(filterparams).toPredicate(version, query, builder);
return documentPath.in(sq.select(version.get("document").as(Document.class)).where(predicate));
}
};
}
生成的请求如下:
select
*
from
( select
document0_.*
from
DOCUMENT document0_
where
document0_.id in (
select
documentve2_.DOC_ID
from
DOCUMENT_VERSION documentve2_
//LOTS OF JOINS TO SUPPORT PREDICATES
where
//LOST OF PREDICATE BUSINESS LOGIC
)
order by
document0_.id desc
)
where
rownum <= ?;
要点是,我有很多数据,请求可以在6分钟内完成。
但是,如果我手动调整使用JOIN而不是subselect的请求,则只需11秒。
select
*
from
( select
document0_.*
from
DOCUMENT document0_
JOIN
(
select
documentve2_.DOC_ID
from
DOCUMENT_VERSION documentve2_
//LOTS OF JOINS TO SUPPORT PREDICATES
where
//LOST OF PREDICATE BUSINESS LOGIC
)
sq ON sq.DOC_ID= document0_.ID
order by
document0_.id desc
)
where
rownum <= ?;
如何更改子查询以加入CriteriaBuilder?
版本:DB是Oracle 11,spring-data-jpa版本1.7.4.RELEASE