`

二十三 iterate查询与N+1次查询的问题

 
阅读更多
test.java

view plaincopy to clipboardprint?
01.import hibernate.HibernateUtil;   
02.  
03.import java.util.Date;   
04.import java.util.Iterator;   
05.  
06.import org.hibernate.Query;   
07.import org.hibernate.Session;   
08.  
09.import domain.Users;   
10.  
11.  
12.  
13.public class test {   
14.  
15.  
16.       
17.    public static void main(String[] args) {   
18.        Users user = new Users();   
19.        user.setBirthday(new Date());   
20.        user.setName("pf1");   
21.        HibernateUtil.add(user);   
22.        user.setName("pf2");   
23.        HibernateUtil.add(user);   
24.        user.setName("pf3");   
25.        HibernateUtil.add(user);   
26.           
27.        iterator();   
28.           
29.           
30.    }   
31.       
32.    static void iterator(){   
33.        Session s = HibernateUtil.getSession();   
34.        Query query = s.createQuery("from Users");   
35.        Iterator<Users> it = query.iterate();   
36.        while(it.hasNext()){   
37.            System.out.println(it.next().getName());   
38.        }   
39.    }   
40.}  
import hibernate.HibernateUtil;

import java.util.Date;
import java.util.Iterator;

import org.hibernate.Query;
import org.hibernate.Session;

import domain.Users;



public class test {


	
	public static void main(String[] args) {
		Users user = new Users();
		user.setBirthday(new Date());
		user.setName("pf1");
		HibernateUtil.add(user);
		user.setName("pf2");
		HibernateUtil.add(user);
		user.setName("pf3");
		HibernateUtil.add(user);
		
		iterator();
		
		
	}
	
	static void iterator(){
		Session s = HibernateUtil.getSession();
		Query query = s.createQuery("from Users");
		Iterator<Users> it = query.iterate();
		while(it.hasNext()){
			System.out.println(it.next().getName());
		}
	}
}
 

执行结果:

Hibernate: insert into Users (ver, name, birthday) values (?, ?, ?)
Hibernate: insert into Users (ver, name, birthday) values (?, ?, ?)
Hibernate: insert into Users (ver, name, birthday) values (?, ?, ?)
Hibernate: select users0_.id as col_0_0_ from Users users0_
Hibernate: select users0_.id as id0_0_, users0_.ver as ver0_0_, users0_.name as name0_0_, users0_.birthday as birthday0_0_ from Users users0_ where users0_.id=?
pf1
Hibernate: select users0_.id as id0_0_, users0_.ver as ver0_0_, users0_.name as name0_0_, users0_.birthday as birthday0_0_ from Users users0_ where users0_.id=?
pf2
Hibernate: select users0_.id as id0_0_, users0_.ver as ver0_0_, users0_.name as name0_0_, users0_.birthday as birthday0_0_ from Users users0_ where users0_.id=?
pf3

可以发现红色那条语句,iterator查询是先查出记录的id号,在需要的时候再去查询,查询时候先从缓存里查找,再从数据库中读取。

由于我的Users是native方式生成主键,所以不会保存在缓存里,因为没访问数据库前不知道数据库生成的id号。

所有的select语句加起来是4条,包括查id的语句,所以一共是N+1次查询。所以缓存没命中的情况下查询效率极低。

同样懒加载的时候也会有N+1次查询的情况,第一次查询出所有当前对象,N次查询查询关联对象。


懒加载也会有N+1次查询
当有个部门它下面有十个员工 我们去查这个部门,当要查询这个部门下的员工时,就会出现11条select语句,一条是
这个部门的查询 另外十条是根据部门id查员工的select语句

如果我查询员工,通过员工去查部门,就不会有N+1次查询,因为这在查员工的时候就把部门信息给查出来了 
这种情况在一对一的关系中特别明显


总结 N+1次查询和懒加载
     1.用Query.iterator可能会有N+1次查询。
     2.懒加载时获取关联对象。
     3.如果打开对查询的缓存即使用list也可能有N+1次查询。


完毕 end!

 

分享到:
评论

相关推荐

    Hibernate缓存机制

    - 当使用`iterate`遍历查询结果时,可能会引发N+1次查询的问题。 - “N+1”中的“1”是指第一次查询,而“N”则是指后续每次查询数据库获取单条记录的次数。 #### 二、缓存使用注意事项 **2.1 效率问题** - ...

    Hibernate缓存详解[文].pdf

    在使用iterate查询时,虽然会将查询到的实体放入缓存,但仍然会产生N+1问题,即发出一条查询ID的SQL,然后根据ID列表逐个查询实体。List()和iterate查询的主要区别在于,List每次都会查询SQL并放入缓存,而iterate在...

    hibernate缓存的问题

    N+1次查询问题是指在首次使用iterate()方法执行条件查询时,会产生额外的n次查询,但在后续相同查询中,性能会得到显著提升。对于大数据量的业务,应当考虑配置合适的缓存策略,避免内存资源过度消耗。 使用...

    Java Hibernate中使用HQL语句进行数据库查询的要点解析

    N+1问题是一个常见的性能瓶颈,尤其是在处理大数据集时。当我们在查询中获取一组对象,然后逐一加载每个对象的相关关联数据时,会触发多次额外的数据库查询。例如,查询所有学生后,再为每个学生加载其课程信息,会...

    牛顿迭代c程序

    其中,x_n 是第n次迭代的近似值,x_n+1 是下一次迭代的近似值。这个公式基于函数在x_n处的切线与x轴的交点作为新的估计值。迭代过程会一直进行,直到达到一定的精度要求(例如,相邻两次迭代的差小于一个设定的阈值...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part2

    全书一共被压缩为5个rar,这是第二个!!!! 其他的请看ID:ljtt123(本人分享) 本博客提供的所有教程的资源原稿均来自于互联网,仅供学习交流之用,切勿进行商业传播。同时,转载时不要移除本申明。如产生任何...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part4

    第1章 xml与dtd 2 1.1 xml的产生 2 1.2 w3c介绍 2 1.3 关于xml的几个问题 3 1.4 xml与html的比较 4 1.4.1 xml将数据与显示分开 5 1.4.2 xml对文档的格式要求更加严格 6 1.4.3 xml有且只能有一个根元素 6 1.5...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part3

    全书一共被压缩为5个rar,这是第三个!!!! 其他的请看ID:ljtt123(本人分享) 本博客提供的所有教程的资源原稿均来自于互联网,仅供学习交流之用,切勿进行商业传播。同时,转载时不要移除本申明。如产生任何...

    hibernate 二级缓存详解

    而且,iterate可能会导致1+N问题,因为即使有缓存,每次迭代时仍需检查数据库是否存在新数据。相比之下,list在某些情况下可能更高效,特别是当配合查询缓存时。 查询缓存可以存储特定查询的结果,使得相同的查询只...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part5

    第1章 xml与dtd 2 1.1 xml的产生 2 1.2 w3c介绍 2 1.3 关于xml的几个问题 3 1.4 xml与html的比较 4 1.4.1 xml将数据与显示分开 5 1.4.2 xml对文档的格式要求更加严格 6 1.4.3 xml有且只能有一个根元素 6 1.5...

    二分法,简单迭代法,牛顿迭代法,埃特金加速收敛法求根

    其核心在于构造一个迭代公式x[n+1] = g(x[n]),并通过迭代的方式逐渐逼近根x0。 #### 实现 简单迭代法的步骤如下: 1. **初始化**:选取一个初始值x0。 2. **迭代计算**:通过迭代公式x[n+1] = g(x[n])计算新的近似...

    Hibernate二级缓存攻略

    然而,对于复杂的查询,如分页或条件查询,使用二级缓存可能仍然存在1+N问题,因为不同的查询条件可能无法充分利用缓存。 总的来说,Hibernate的二级缓存是提升应用性能的有效手段,但正确配置和使用缓存策略是至关...

    牛顿法 迭代 C++ 计算方法

    其中,x_n 是当前的估计值,x_{n+1} 是下一个迭代的估计值,f'(x_n) 是f(x)在x_n处的导数。如果方程f(x)连续且在x_n附近可导,那么随着迭代次数的增加,x_n将逐渐接近方程的实数根。 在C++中实现牛顿法,我们需要...

    hibernate对二级缓存的理解

    然而,对于使用相同的查询条件,先list后iterate的方式并不能保证始终使用缓存,因为每次查询的条件可能不同,可能会导致1+N问题。 查询缓存是解决这一问题的一种方式,它能缓存查询结果。启用查询缓存后,相同的...

    对二级缓存的详细理解

    然而,依赖于缓存进行多次相同查询以减少数据库访问并不总是有效,因为查询条件通常会变化,可能导致部分数据从缓存中获取,部分数据仍需从数据库读取,引发1+N问题。 查询缓存则可以缓存查询结果,避免重复执行...

    数学建模迭代实验报告.docx

    对于简单的迭代,如x_{n+1} = (x_n + 2/x_n)/2,我们可以观察到迭代过程如何收敛于不动点。在Mathematica中,可以使用`Iterate`函数实现迭代: ```mathematica Iterate[f_, x0_, n_Integer] := Module[{t = {}, ...

    sidekick:适用于Python的功能性编程库

    搭档 Sidekick是一个库,可为您提供功能上的超能力。 Sidekick实现了功能和类型的功能标准库,旨在使Python中的功能编程更加...&gt;&gt;&gt; fibonacci = sk.iterate((X + Y), 1 , 1 ) &gt;&gt;&gt; fibonacci sk.iter([1, 1, 2, 3, 5, 8

    list的分批处理实现的几种方式.docx

    Stream.iterate(0, n -&gt; n + 1).limit(limit) .forEach(i -&gt; mglist.add(list.stream() .skip(i * partialLimit) .limit(partialLimit) .collect(Collectors.toList()))); ``` 3. **使用`Stream`的`parallel`...

    Polynomiography of Newton method for one parameter三次多项式:一参数三次多项式的牛顿法多项式的生成-matlab开发

    \[ z_{n+1} = z_n - \frac{p(z_n)}{p'(z_n)} \] 对于给定的三次多项式,其导数为: \[ p'(z) = 3z^2 + (c - 1) \] 我们的目标是找到多项式\( p(z) \)的临界点,即令\( p(z) = 0 \)的点。特别地,我们要检查0是否是...

Global site tag (gtag.js) - Google Analytics