SQL中N+1问题已经MyBaits中的解决方案
来源:互联网 发布:克里斯埃文斯知乎 编辑:程序博客网 时间:2024/06/05 20:47
概括地讲,N+1 查询问题可以是这样引起的:
- 你执行了一个单独的 SQL 语句来获取结果列表(就是“+1”)。
- 对返回的每条记录,你执行了一个查询语句来为每个加载细节(就是“N”)。
这个问题会导致成百上千的 SQL 语句被执行。这通常不是期望的。
- 如果当SQL数据库中select语句数目过多,就会影响数据库的性能,如果需要查询n个Customer对象,那么必须执行n+1次select查询语句,下文就将为您讲解这个n+1次select查询问题。
在Session的缓存中存放的是相互关联的对象图。默认情况下,当Hibernate从数据库中加载Customer对象时,会同时加载所有关联的Order对象。以Customer和Order类为例,假定ORDERS表的CUSTOMER_ID外键允许为null,图1列出了CUSTOMERS表和ORDERS表中的记录。
以下Session的find()方法用于到数据库中检索所有的Customer对象:
List customerLists=session.find("from Customer as c");
运行以上find()方法时,Hibernate将先查询CUSTOMERS表中所有的记录,然后根据每条记录的ID,到ORDERS表中查询有参照关系的记录,Hibernate将依次执行以下select语句:
select * from CUSTOMERS;
select * from ORDERS where CUSTOMER_ID=1;
select * from ORDERS where CUSTOMER_ID=2;
select * from ORDERS where CUSTOMER_ID=3;
select * from ORDERS where CUSTOMER_ID=4
Hibernate在检索与Customer关联的Order对象时,使用了默认的立即检索策略。这种检索策略存在两大不足:
(1) select语句的数目太多,需要频繁的访问数据库,会影响检索性能。如果需要查询n个Customer对象,那么必须执行n+1次select查询语句。这就是经典的n+1次select查询问题。这种检索策略没有利用SQL的连接查询功能,例如以上5条select语句完全可以通过以下1条select语句来完成:
select * from CUSTOMERS left outer join ORDERS on CUSTOMERS.ID=ORDERS.CUSTOMER_ID
以上select语句使用了SQL的左外连接查询功能,能够在一条select语句中查询出CUSTOMERS表的所有记录,以及匹配的ORDERS表的记录。
(2)在应用逻辑只需要访问Customer对象,而不需要访问Order对象的场合,加载Order对象完全是多余的操作,这些多余的Order对象白白浪费了许多内存空间。
为了解决以上问题,Hibernate提供了其他两种检索策略:延迟检索策略和迫切左外连接检索策略。延迟检索策略能避免多余加载应用程序不需要访问的关联对象,迫切左外连接检索策略则充分利用了SQL的外连接查询功能,能够减少select语句的数目。
MyBatis默认采用延迟加载这样的查询,有一个好处,因此你可以分散这些语句同时运行的消耗。然而,如果你加载一个列表,之后迅速迭代来访问嵌套的数据,你会调用所有的延迟加载,这样的行为可能是很糟糕的
<resultMap id="blogResult" type="Blog"> <association property="author" column="author_id" javaType="Author" select="selectAuthor"/></resultMap><select id="selectBlog" resultMap="blogResult"> SELECT * FROM BLOG WHERE ID = #{id}</select><select id="selectAuthor" resultType="Author"> SELECT * FROM AUTHOR WHERE ID = #{id}</select>
这种方式很简单, 但是对于大型数据集合和列表将不会表现很好。问题就是我们熟知的 “N+1 查询问题”。如果查询的结果不需要Author对象是,就不用为Blog配置Author的查询,从而避免N+1问题的发生。
- SQL中N+1问题已经MyBaits中的解决方案
- Mybaits中遇到的问题
- SSH框架中N+1查询问题与解决方案
- 【sql】n+1问题
- 在myBaits中打印sql语句
- mybaits中的返回结果resultType的问题
- SQL中的n+1次select语句查询问题
- SQL中的n+1次select语句查询问题
- SQL中的n+1次select语句查询问题
- IDEA中使用MyBaits的配置问题
- 1+n问题阐述与解决方案
- Ibatis/MyBaits 1:N 一对多关系 处理
- hibernate中的N+1问题
- hibernate中的1+N问题
- Hibernate中的“1+N”问题
- MyBatis中的N+1问题
- hibernate中的N+1问题
- hibernate中的N+1问题
- nyoj 325 zb的生日【0-1背包】
- String
- 实现顺序表以及顺序表的简单运算
- 观察者模式
- Android sqlite3工具的使用
- SQL中N+1问题已经MyBaits中的解决方案
- 题目1098:字母统计
- 出现次数最多的数
- spark1.6.0+Hadoop2.6.0+Scala-2.11.7 搭建分布式集群
- 2014年普级组模拟试题一 五香豆腐
- 10017---Managing Solr Search Configuration
- Java FileInputStream没有读取文件会发生什么情况
- Block中的循环引用问题
- Educational Codeforces Round 11---B-Seating On Bus