如果当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;

通过以上5条select语句,Hibernate最后加载了4个Customer对象和5个Order对象,在内存中形成了一幅关联的对象图,参见图2。

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语句的数目。

SQL中的n+1次select语句查询问题相关推荐

  1. SQL基础学习总结:3(select语句基础算术运算符比较运算符)

    select语句基础 列的查询 从表中选取数据时需要使用select语句,通过select语句查询并选取出必要数据的过程称为匹配查询或查询. 语法结构如下: select <列名1>,&l ...

  2. mysql 查询指定字段数据_MySQL使用select语句查询指定表中指定列(字段)的数据

    本文介绍mysql数据库中执行select查询语句,查询指定列的数据,即指定字段的数据. 再来回顾一下sql语句中的select语句的语法: select 语句的基本语法: select from w ...

  3. GBase 8s SQL 指南:教程———3编写SELECT语句

    3编写SELECT语句 SELECT语句是最重要且最复杂的SQL语句.可使用它和SQL语句INSERT. UPDATE和DELETE操纵数据.可以使用SELECT语句从数据库检索数据.将它用作 INS ...

  4. mysql select 指定列_MySQL使用select语句查询指定表中指定列(字段)的数据

    本文介绍mysql数据库中执行select查询语句,查询指定列的数据,即指定字段的数据. 再来回顾一下sql语句中的select语句的语法: select 语句的基本语法: select from w ...

  5. sql中“delete from 表名”表示_SQL查询语句知识点总结

    为什么要学习SQL? 数据分析岗位的基础技能:SQL语句和会使用SQL语句操纵数据库软件: 数据量增大的工具需求:excel处理十万以内的数据:数据量增大,需要使用更快速便捷的工具分析数据. SQL知 ...

  6. 【SQL学习笔记】一、select语句

    SQL有别于其他的编程语言的一点在于首先处理的并不是写在第一行的语句(select),而是from字句. 为了更详细的了解select语句的每个部分,举例如下: 该语句返回的结果是下订单超过4次的女顾 ...

  7. SQL从入门到入魔之select简单查询

    准备数据: /*新建学生表stu*/ create table stu( id int not null PRIMARY key auto_increment comment'主键', name va ...

  8. SQL中的多表关联和子查询

    多表关联: 连接查询: 1.内关联:相当于两个表中的公共部分的数据 select * from 表1 join 表2 on 表1相同的值=表2相同的值 2.外关联: 左关联:以左表为主,右表能关联上的 ...

  9. access在sql中横向求和_如何在Access查询中增加总和、平均查询列

    Access的查询对象的操作,是个头痛的问题.尤其是高中信息技术考试中的查询对象的操作,如果涉及到在查询中增加求和或求平均的查询列,那么,可以算是一道难题了. 下面,本文,就给大家总结一下关于这道题, ...

  10. SQL中的in、not in语句遇到null时的坑点

    背景介绍 前两天做问题排查的时候,写了一条sql,但是并没有如期地查到数据(确实是有数据的),SQL如下: SELECT tar.*FROM tb_account_relation tarWHERE ...

最新文章

  1. 【机器学习】搞懂机器学习的常用评价指标!
  2. android 中ScrollView的使用
  3. 35 岁程序员的独家面试经历
  4. HDU6428-Calculate-数论函数
  5. IDEA主题设置与eclipse代码风格一致
  6. CentOS7.4下载与安装
  7. 6-5-2:STL之stack和queue——双端队列deque
  8. C语言课后习题(3)
  9. 万年5W充电头再见!2019新iPhone或将标配18W快充头
  10. 95-130-410-源码-source-RabbitMQ相关-RabbitMQ Connector
  11. java中的汇编指令_查看Java的汇编指令
  12. 功能强大的安卓刷机软件-刷机精灵提供下载
  13. 现代笑话二则2 木子家创作
  14. ReactOS LiveUSB
  15. web前端学习到什么程度可以面试工作
  16. JavaScript中pageX pageY offsetX offsetY区别
  17. 【Ajax】form表单
  18. 知乎个人创作者如何认证?附图文认证教程
  19. 《C Primer Plus》第5章复习题与编程练习
  20. 页面可用性之浏览器默认字体与CSS中文字体

热门文章

  1. python 中英文 分离_Python 将字符串的中英文分离的完整代码
  2. e站host地址_IP地址和物理地址的区别和联系
  3. mysql sqlserver 跨库查询_SQLServer跨库查询
  4. html缩放背景不缩放_缩放并不可怕。
  5. Typora无法打开提示安装新版本解决办法
  6. Java 读取扫描枪
  7. 西交学电气还是计算机,上南大还是上西交学电气
  8. win10系统服务器管理器,win10服务管理器,详细教您Win10服务管理器怎样打开
  9. MATLAB中绘制椭圆
  10. linux 网桥浅析