- http://hi.baidu.com/victorlin23/blog/item/8b7a3382670cd9b16d811963.html
Find()方法下FetchType.LAZY、FetchType.EAGER、@Fetch(FetchMode.JOIN)的区别2010-08-27 16:13结论:1.使用
例如:@ManyToOne(fetch = FetchType.LAZY)将会产生N+1的问题。
2.使用:@ManyToOne(fetch = FetchType.EAGER)将会使用join查询,推断hibernate对eaer进行了优化并不会产生N+1的问题。
3.使用:@Fetch(FetchMode.JOIN)将和第2项描述的执行效果和步骤是一样的,都是使用join 可以得出官方文档:Hibernate_Annotations.pdf第62页描述的Table 2.3. Lazy and fetch options equivalent是正确的。完全等价。hibernate重载了EJG的Fetch注解
一、@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "SERVICE_ID", referencedColumnName = "ID")
public SystemServiceInfo getSysService() {
return sysService;
}
使用Lazy查询,由于需要立即访问触发了数据库查询。这个时候出现了N+1的问题:
select
count(*) as y0_
from
at_t_client_and_service this_
inner join
AT_T_CLIENT_INFO clientinfo1_
on this_.CLIENT_ID=clientinfo1_.id
where
(
1=1
)
and (
clientinfo1_.id = ?
)
Hibernate:
select
*
from
( select
this_.id as id56_1_,
this_.URL as URL56_1_,
this_.CLIENT_ID as CLIENT15_56_1_,
this_.CREATE_DATE as CREATE3_56_1_,
this_.SERVICE_ID as SERVICE16_56_1_,
this_.NAME_SPACE_URL as NAME4_56_1_,
this_.LOCAL_PART_SERVICE as LOCAL5_56_1_,
this_.LOCAL_PART_PORT as LOCAL6_56_1_,
this_.PERIOD_BEGIN_DATE as PERIOD7_56_1_,
this_.PERIOD_END_DATE as PERIOD8_56_1_,
this_.FTP_FLAG as FTP9_56_1_,
this_.FTP_RELATIVE_FLAG as FTP10_56_1_,
this_.FTP_PATH as FTP11_56_1_,
this_.FTP_PORT as FTP12_56_1_,
this_.FTP_USER as FTP13_56_1_,
this_.FTP_PASSWORD as FTP14_56_1_,
clientinfo1_.id as id63_0_,
clientinfo1_.CLIENT_ID as CLIENT2_63_0_,
clientinfo1_.CLIENT_IP as CLIENT3_63_0_,
clientinfo1_.CLIENT_NAME as CLIENT4_63_0_,
clientinfo1_.REGEST_TIME as REGEST5_63_0_,
clientinfo1_.REMARK as REMARK63_0_
from
at_t_client_and_service this_
inner join
AT_T_CLIENT_INFO clientinfo1_
on this_.CLIENT_ID=clientinfo1_.id
where
(
1=1
)
and (
clientinfo1_.id = ?
) )
where
rownum <= ?
Hibernate:
select
systemserv0_.id as id28_0_,
systemserv0_.COMM as COMM28_0_,
systemserv0_.SERVICE_NAME as SERVICE3_28_0_,
systemserv0_.CREATE_DATE as CREATE4_28_0_
from
AT_T_SERVICE systemserv0_
where
systemserv0_.id=?
Hibernate:
select
systemserv0_.id as id28_0_,
systemserv0_.COMM as COMM28_0_,
systemserv0_.SERVICE_NAME as SERVICE3_28_0_,
systemserv0_.CREATE_DATE as CREATE4_28_0_
from
AT_T_SERVICE systemserv0_
where
systemserv0_.id=?
二、@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "SERVICE_ID", referencedColumnName = "ID")
public SystemServiceInfo getSysService() {
return sysService;
}
并未出现N+1的问题
Hibernate:
select
count(*) as y0_
from
at_t_client_and_service this_
inner join
AT_T_CLIENT_INFO clientinfo1_
on this_.CLIENT_ID=clientinfo1_.id
where
(
1=1
)
and (
clientinfo1_.id = ?
)
Hibernate:
select
*
from
( select
this_.id as id61_2_,
this_.URL as URL61_2_,
this_.CLIENT_ID as CLIENT15_61_2_,
this_.CREATE_DATE as CREATE3_61_2_,
this_.SERVICE_ID as SERVICE16_61_2_,
this_.NAME_SPACE_URL as NAME4_61_2_,
this_.LOCAL_PART_SERVICE as LOCAL5_61_2_,
this_.LOCAL_PART_PORT as LOCAL6_61_2_,
this_.PERIOD_BEGIN_DATE as PERIOD7_61_2_,
this_.PERIOD_END_DATE as PERIOD8_61_2_,
this_.FTP_FLAG as FTP9_61_2_,
this_.FTP_RELATIVE_FLAG as FTP10_61_2_,
this_.FTP_PATH as FTP11_61_2_,
this_.FTP_PORT as FTP12_61_2_,
this_.FTP_USER as FTP13_61_2_,
this_.FTP_PASSWORD as FTP14_61_2_,
clientinfo1_.id as id63_0_,
clientinfo1_.CLIENT_ID as CLIENT2_63_0_,
clientinfo1_.CLIENT_IP as CLIENT3_63_0_,
clientinfo1_.CLIENT_NAME as CLIENT4_63_0_,
clientinfo1_.REGEST_TIME as REGEST5_63_0_,
clientinfo1_.REMARK as REMARK63_0_,
systemserv4_.id as id29_1_,
systemserv4_.COMM as COMM29_1_,
systemserv4_.SERVICE_NAME as SERVICE3_29_1_,
systemserv4_.CREATE_DATE as CREATE4_29_1_
from
at_t_client_and_service this_
inner join
AT_T_CLIENT_INFO clientinfo1_
on this_.CLIENT_ID=clientinfo1_.id
left outer join
AT_T_SERVICE systemserv4_
on this_.SERVICE_ID=systemserv4_.id
where
(
1=1
)
and (
clientinfo1_.id = ?
) )
where
rownum <= ?
三、 @ManyToOne
@Fetch(FetchMode.JOIN)
@JoinColumn(name = "CLIENT_ID", referencedColumnName = "ID")
public ClientInfo getClientInfo() {
return clientInfo;
}
未出现N+1的问题。而且和第二种配置的效果完全一样,证实了hibernate做eager时进行了优化,使用了ourtjoin,并不会产生N+1问题。
Hibernate:
select
count(*) as y0_
from
at_t_client_and_service this_
inner join
AT_T_CLIENT_INFO clientinfo1_
on this_.CLIENT_ID=clientinfo1_.id
where
(
1=1
)
and (
clientinfo1_.id = ?
)
Hibernate:
select
*
from
( select
this_.id as id35_2_,
this_.URL as URL35_2_,
this_.CLIENT_ID as CLIENT15_35_2_,
this_.CREATE_DATE as CREATE3_35_2_,
this_.SERVICE_ID as SERVICE16_35_2_,
this_.NAME_SPACE_URL as NAME4_35_2_,
this_.LOCAL_PART_SERVICE as LOCAL5_35_2_,
this_.LOCAL_PART_PORT as LOCAL6_35_2_,
this_.PERIOD_BEGIN_DATE as PERIOD7_35_2_,
this_.PERIOD_END_DATE as PERIOD8_35_2_,
this_.FTP_FLAG as FTP9_35_2_,
this_.FTP_RELATIVE_FLAG as FTP10_35_2_,
this_.FTP_PATH as FTP11_35_2_,
this_.FTP_PORT as FTP12_35_2_,
this_.FTP_USER as FTP13_35_2_,
this_.FTP_PASSWORD as FTP14_35_2_,
clientinfo1_.id as id47_0_,
clientinfo1_.CLIENT_ID as CLIENT2_47_0_,
clientinfo1_.CLIENT_IP as CLIENT3_47_0_,
clientinfo1_.CLIENT_NAME as CLIENT4_47_0_,
clientinfo1_.REGEST_TIME as REGEST5_47_0_,
clientinfo1_.REMARK as REMARK47_0_,
systemserv4_.id as id58_1_,
systemserv4_.COMM as COMM58_1_,
systemserv4_.SERVICE_NAME as SERVICE3_58_1_,
systemserv4_.CREATE_DATE as CREATE4_58_1_
from
at_t_client_and_service this_
inner join
AT_T_CLIENT_INFO clientinfo1_
on this_.CLIENT_ID=clientinfo1_.id
left outer join
AT_T_SERVICE systemserv4_
on this_.SERVICE_ID=systemserv4_.id
where
(
1=1
)
and (
clientinfo1_.id = ?
) )
where
rownum <= ?
参考官方文档:Hibernate_Annotations.pdf P62。The Hibernate annotations overrides the EJB3 fetching options
分享到:
相关推荐
在IT行业中,数据库查询优化是提升系统性能的关键环节之一,而"Ibatis N+1问题"是使用MyBatis框架时常见的性能瓶颈。这个问题通常出现在一对多或者多对多的关联查询中,导致了大量的数据库交互,严重影响了应用的...
浅谈Hibernate n+1问题 Hibernate 是一个基于Java的持久层框架,它提供了对数据库的访问和管理功能。在使用 Hibernate 进行数据访问时,经常会遇到一个问题,即 n+1 问题。该问题是指在一次数据库查询中,需要执行...
HIBERNATE的N+1查询问题 关联查询时
N+1问题 N+1问题是数据库访问中最常见的一个性能问题,首先介绍一下什么是N+1问题: 举个例子,我们数据库中有两张表,一个是Customers,一个是Orders。Orders中含有一个外键customer_id,指向了Customers的主键id。...
Prisma如何解决N + 1问题-2020年Prisma日 该存储库包含2020年Prisma Day演讲“ Prisma如何解决N + 1问题”的相应代码。 结果 名称 要求/秒 字节/序列 阿波罗PG 2.6 625 kB 阿波罗棱镜发现 7.8 1.87兆字节 ...
1. **3N+1问题**: 一种简单的数学游戏,对于任何正整数n,通过特定规则操作,最终会收敛至1。 2. **循环结构**: 使用`for`和`while`循环来遍历指定范围内的整数并计算每个数的数列长度。 3. **条件判断**: 利用`if-...
这里讨论的是一个具有特定形式的递推关系:\( S_{n+2} = pS_{n+1} + qS_n \),其中 \( n \geq 1 \),\( S_1 \) 和 \( S_2 \) 是数列的初始项,而 \( p \) 和 \( q \) 是常数。这个递推关系可以用来找到数列的一般项 ...
简介 在orm框架中,比如hibernate和mybatis都可以设置关联对象,比如user对象关联dept ...dept,是n次,所以是n+1问题,其实叫1+n更为合理一些。 mybatis配置 UserMapper.xml <result column
我发现自己无法通过测试来验证另一个N + 1问题后,这个宝石诞生了。 安装将此行添加到您的应用程序的Gemfile中: group :test do gem "n_plus_one_control"end 然后执行: $ bundle用法规范首先,将NPl
关于该项目在调查SpringBoot应用程序中的性能问题时,我发现了臭名昭著的N + 1查询问题,该问题使我的服务性能丧失了。 有关更多详细信息,请查看文章消除Spring Hibernate N + 1查询。 在设法解决了这个问题之后,...
割圆多项式Q2^(n+1)(x)的分解,武跟强,李研超,本文研究了割圆多项式Q2^(n+1)(x)的分解问题。解决问题用到的方法为数论中的理论。最后给出了Qp^(n+1)(x)的分解及计数定理,并且得到了q�
尽管1到100的项之和可以精确计算,但当n变得非常大时,计算结果会非常接近自然对数ln(n),具体公式为Hn ≈ ln(n) + γ,其中γ是欧拉-马斯cheroni常数,大约等于0.5772156649。 在C#中,可以使用`Math.Log`函数来...
\[ S_n = n^1 + n^2 + n^3 + \ldots + n^k = \frac{n^{k+1} - 1}{n - 1} \] 当 \( n = 1 \) 时,由于 \( 1^k = 1 \) 对所有正整数 \( k \) 成立,所以 \( n^1 + n^2 + \ldots + n^k \) 的和为 \( k \)。根据题目,\...
6. 逻辑推理和错误证明:文档中通过假设n^5+n^4+1不是素数,然后通过推理发现这个假设会导致矛盾(n^3-n+1=1或n^2+n+1=1,但n=0或n=-1与n大于1矛盾),从而证明了原假设是错误的,即n^5+n^4+1实际上是素数。...
与其他库(例如db-query-matchers,rspec-sqlimit等)不同,使用n_plus_one_cont N +1 Control RSpec和Minitest匹配器可以防止N + 1查询问题。 为什么还有另一个断言来声明数据库查询呢? 与其他库(例如db-query-...
1. 接受用户输入的正整数`n`。 2. 使用公式`p = n^2 + n + 41`计算`p`的值。 3. 检查`p`是否为素数。这可以通过试除法实现,即从2到`sqrt(p)`遍历所有可能的因子,如果找到任何因子能整除`p`,则`p`不是素数。 下面...
其中满足\( n_1 \geq n_2 \geq \ldots \geq n_k \geq 1 \),且\( k \geq 1 \)。每个满足条件的表达式都称为\( n \)的一个划分。 #### 示例解释 以正整数6为例,它具有以下11种不同的划分方式: - 6 - 5 + 1 - 4 + 2...
在这个Collatz问题的实现中,函数会根据Collatz规则对给定的n进行处理,如果n为偶数,则调用自身传入n/2,若为奇数,则传入3*n+1。这个过程一直持续到n等于1为止,从而形成一个递归链。 C++源代码可能如下: ```...