当前位置: 首页 > 知识库问答 >
问题:

JPA中显式连接和隐式连接的区别是什么?(性能)

西门逸仙
2023-03-14

这些天我正在阅读JPA。我了解到可以在JPQL中使用显式隐式JOIN

显式连接

em.createQuery(“从Book b JOIN b.publisher p中选择b.title、p.name”)。getResultList();

隐式联接

em.create查询("SELECTb.title,b.publisher.nameFrom Book b"). getResultList();

这些示例的来源:链接

我的问题是:显式连接和隐式连接在性能方面有什么区别吗?

更新

我读过你写的@MatteoBaldi和@Kayaman,我做了一些测试,我想和你分享结果。

我创建了两个实体:学生和课程,我有一个多个(许多学生参加一个课程)。我使用了JPA的EcpliseLink实现。

查询=从课程中选择学生和DummyField,执行场景:

  1. manytone(defaultFetch-

所以在我的测试环境中(EclipseLink,…)我的SQL查询与JPQL查询生成的SQL查询相同。因此,我可以说,性能将是相同的(当然,我再次说,在我的测试条件中,我希望有人能够确认/纠正我的结果,并制定一个一般规则)。


共有3个答案

缑桐
2023-03-14

它们应该是相同的,但实际上主要取决于底层数据库。在当前环境中测试性能的一种快速方法是启用SQL日志记录,跟踪您的jpql中包含的本机查询,并直接使用SQL客户端进行尝试。

侯向文
2023-03-14

通常,我总是显式地加入每个。主要目标是更清楚地了解查询正在做什么以及如何做,从而拥有一个更可预测的SQL,并对查询进行未来的更改。

但我可以举一个例子,其中隐式连接比显式连接具有更高的性能,即使在大多数情况下,这种性能增益也非常小,而且就个人而言,不会承担风险(我稍后会解释什么风险)。

想象一下,您正试图将所有书籍与同一个出版商进行分组。使用显式JOIN,这是JPQL:

 SELECT count(publisher.id) 
 FROM FROM Book b
 JOIN b.publisher publisher
 WHERE publisher.id = 1
 GROUP by publisher.id

此查询是可读的,没有任何重复,并且此查询中的任何更改(如添加另一个条件)将按预期维护生成的SQL。

现在,使用隐式JOIN:

 SELECT count(b.publisher.id) 
 FROM FROM Book b
 WHERE b.publisher.id = 1
 GROUP by b.publisher.id

我们有b.publisher的<代码>。id重复三次。如果您添加另一个条件,那么Hibernate的JPQ解释可能会更改生成的SQL,从而执行不必要的连接,如Kayaman答案中所述。

但是这个带有隐式JOIN的JPQL不会在生成的SQL上对发布者表执行额外的JOIN,因为他可以使用中的idpublished_id

 SELECT Count(b.published_id) AS col_0_0_ 
 FROM   Book b
 WHERE  b.published_id = ? 
 GROUP  BY b.published_id

以及SQL显式连接和额外的连接:

 SELECT Count(published.id) AS col_0_0_ 
 FROM   Book b
 INNER JOIN published published1_ 
           ON b.published_id = published1_.id 
 WHERE  published_id = ? 
 GROUP  BY published_id

但是只有当发布者的外键位于book端时才会发生这种情况。在这种情况下是正确的方法,但是有一些映射,外键可能位于表的任何一侧,因此显式和隐式JPQLs查询可以生成相同的SQL。

根据我的经验,显式JOIN总是更好的选择。Hibernate并不总是理解在同一查询上复制的相同隐式JOIN是同一JOIN的一部分,从而创建了未优化/奇怪的SQL。

郎鸿朗
2023-03-14

它们的解析方式不同,因此它们最终可能会成为不同的SQL查询,具体取决于查询、实体关系和其他类似的东西。理想情况下,只要JPQL查询在做同样的事情,就应该没有区别,但它并不总是这样工作。

推荐的方法是使用显式联接,这还有其他优点,例如在惰性关系上指定联接获取。这个问题过于关注性能,似乎很明显,如果其中一个性能更好,但给出了相同的结果,那么就没有理由使用较慢的一个。

无论使用哪种语法,启用SQL日志记录查看生成的查询都是验证应用程序是否正在执行预期查询的好方法。您不能仅仅依赖JPQL,您需要了解和理解您的数据库,这样您就不会仅仅使用“混淆层”作为\u horse\u(没有\u name喜欢调用ORM frameworks;)

 类似资料:
  • 我在查询中有这个疑问 平等吗?。。。我什么时候可以使用? 提前感谢。

  • 问题内容: 显式内部连接与隐式内部连接是否存在效率差异?例如: 与 问题答案: 在性能方面,它们是完全相同的(至少在SQL Server中)。 PS:请注意,自SQL Server 2005起不赞成使用该语法。(仍支持问题中使用的语法) 弃用“旧样式” JOIN语法:只是部分事情

  • 问题内容: 来自http://www.dbspecialists.com/files/presentations/semijoins.html 两个表之间的“ nti- join”返回第一个表中的行,其中第二个表中没有找到匹配项。反联接本质上是与半联接相反的:半联接返回在第一个表中找到至少一个匹配项 的每一行的一个副本,而反联接则返回半联接中的每一行的一个副本。未找到匹配的第一个表 。 是不是“返

  • 内连接,显示两个表中有联系的所有数据; 左链接,以左表为参照,显示所有数据,右表中没有则以null显示 右链接,以右表为参照显示数据,,左表中没有则以null显示

  • 本文向大家介绍MySQL 的内连接、左连接、右连接有什么区别?相关面试题,主要包含被问及MySQL 的内连接、左连接、右连接有什么区别?时的应答技巧和注意事项,需要的朋友参考一下 内连接关键字:inner join;左连接:left join;右连接:right join。 内连接是把匹配的关联数据显示出来;左连接是左边的表全部显示出来,右边的表显示出符合条件的数据;右连接正好相反。

  • 假设您有一个QueryDSL查询,如下所示: 这与下面的(功能)有什么不同? 在我看来,双方都能解决用户所在地必须是梵蒂冈城的问题。此外,这两个对象都返回允许在对象图中导航的对象。 那么有什么区别吗?为什么不直接使用第二个更紧凑的呢? 编辑:他们生成不同的JPQL,这是肯定的,但我不确定最终结果是否有任何不同。我们为什么要明确列出我们正在做什么加入? 编辑2:似乎它们可能是相同的...http:/