【发布时间】:2014-07-07 12:10:32
【问题描述】:
我有两个 JPA 实体
public class Job {
@ManyToOne
@JoinColumn(name = "service")
public Service service;
@Column(name = "queue_time")
public Long queueTime;
@Column(name = "run_time")
public Long runTime;
}
public class Service {
@Id
@Column(name = "id")
public Long id;
@Column(name = "name")
public String name;
@Column(name = "host")
public String host;
}
现在我想用 JPQL 做一些聚合查询:
SELECT job.service.id, AVG(job.queueTime), AVG(job.runTime) FROM Job job GROUP BY job.service.id
生成的 SQL 查询(我使用的是 MySQL 数据库)如下所示:
SELECT t0.id, AVG(t1.queueTime), AVG(t1.runTime) FROM Service t0, Job t1 WHERE (t0.service = t1.id) GROUP BY t0.id
如您所见,JPA 将我的 JPQL 查询转换为带有连接的 SQL 查询。然而,这大大减慢了查询速度。以下 SQL 查询的执行速度快了约 6 倍,并返回完全相同的结果集:
SELECT t1.service, AVG(t1.queueTime), AVG(t1.runTime) FROM Job t1 GROUP BY t1.service
如果我将 JPQL 查询更改为
SELECT job.service, AVG(job.queueTime), AVG(job.runTime) FROM Job job GROUP BY job.service
生成的 SQL 查询如下所示:
SELECT t0.id, t0.name, t0.host AVG(t1.queueTime), AVG(t1.runTime) FROM Service t0, Job t1 WHERE (t0.service = t1.id) GROUP BY t0.id, t0.name, t0.host
有没有办法编写只查询作业表而不连接服务表的 JPQL?
【问题讨论】:
-
如果您关心性能,为什么不使用 NativeQuery?
-
因为软件必须在 Postgres、MySQL、DB2 和 MS SQL Server 等多个 DBMS 上运行
-
据我所知,您没有使用任何供应商特定的 sql 扩展。为什么它应该是一个问题?
-
嗯,你说得对,我应该试一试 :-) 但无论如何我都会对与 JPQL 相关的答案感兴趣。
-
Native SQL 是一种选择,在 Job 中为外键添加一个基本映射以便它可以在 JPQL 查询中使用是另一种选择。 EclipseLink 还允许在外键上创建查询键,因此它也可以像映射一样用于查询。见wiki.eclipse.org/EclipseLink/UserGuide/JPA/…
标签: jpa eclipselink jpql