文档章节

两种极端情况的案例:N+1次查询和笛卡尔积

猪刚烈
 猪刚烈
发布于 2014/10/12 11:39
字数 926
阅读 22
收藏 0

前一篇文章两种极端:频繁的查询和巨大的结果集讲到了Hibernate加载数据时可能会出现的两种极端情况:频繁的查询和一次查出巨大的结果集。其中:N+1次查询是前一种情况的一个典型案例,笛卡尔积则是后一种情况的典型案例。下面分别简单地再总结一下这两种极端案例出现的原因以及调优方法。

 

一.N+1次查询

    如果一个集合是lazy loading的,那么在第一次访问到这个集合时,hibernate会生成一个select被这个集合加载出来。这是N+1中的1。紧接着,在迭代这个集合的过程中,如果要访问集合元素所依赖的其他关联对象时,若它的关联对象也是lazy loading的,那么hibernate会生成一个select从数据库中加载出这个关联对象。这样,N次循环就会生成n个select,这就是N+1中的N.

    解决N+1次查询需要在制定动态抓取策略时eager fetch出集合和集合元素的依赖对象,这样只会生成一条SQL。具体做法是在HOL中,使用fetch关键字来抓取所需要的对象。在Criteria中使用setFetchMode方法设置目标抓取对象。具体示例请参考JPwH-13.5.2

 

 

二.笛卡尔积

    N+1次查询的反面就是笛卡尔积。一般来说,通过定制动态抓取策略,不会加载出我们不需要的数据,但是有一种情况下,即使我们只加载必需对象也会造成大量数据被select出来,这就是抓取“平行”集合导致的笛卡尔积。

    例如:一个Forum有一个Moderator集合,大小为3和一个Thread集合,大小为100。如果在加载Forum时,单独抓取Moderator集合,结果集是3,单独抓取Thread集合,结果集是100,同时抓取这两个集合的结果集是两个集合的加乘(也就是笛卡尔积)为:3*100.如果还有第三个集合,大小是50的话,那结果集就会变成3*100*50. 因此我们可以看到:抓取“平行”集合会产生笛卡尔积,如果集合很多或集合中的元素很多,会使结果集急剧的膨胀。一个巨大的结果集所带来的性能损失是什么呢?想想数据库服务器处理这个条数据所花的时间,占用的服务器的内存,通过网络传输这些数据,以即到了应用服务器占用的内存和hibernate封装这些数据所花费的时间,和这些开销相比,分成两三个SQL(会成数量级的减小结果集)来获取数据要快得多得多。

    HIbernate并不禁止我们产生笛卡尔积,也就是说,你可以在一个抓取计划中抓取多个“平行”集合。但是有一个例外,就是bag集合。Hibernate不允许同时抓取两个以上的bag集合。这是因为:The resultset of a product can’t be converted into bag collections, because Hibernate can’t know which rows contain duplicates that are valid (bags allow duplicates) and which aren’t.

    对于“平行”集合的问题,在抓取时要灵活应对,如果预计到结果集会很大,那么就不要使用join fetch,而要使用subselect fetch!subselect fetch是平行集合的推荐优化方案。

    关于N+1次查询和笛卡尔积,请参考JPwH_13.2.5节。

 

 

 

 

   

 

 

 

本文转载自:http://blog.csdn.net/bluishglc/article/details/5571931

共有 人打赏支持
猪刚烈
粉丝 22
博文 708
码字总数 110
作品 1
海淀
程序员
oracle多表查询之经典面试题

一、笛卡尔积 概念 笛卡尔乘积是指在数学中,两个集合X和Y的笛卡尓积(Cartesian product),又称直积,表示为X × Y,第一个对象是X的成员而第二个对象是Y的所有可能有序对的其中一个成员。...

lkee6760
2017/04/26
0
0
资金项目性能优化

一、项目背景 该项目是一个对资金还、回款改造的项目。以前的做法是,在签约或者发生标转让的时候生成回款信息,直接插入回款表,下次回款时从回款表里面查找。现在这张表有2亿+条数据,100...

liangxiao
2016/05/27
90
0
【SQL】—多表查询的几种连接方式

前言 最近在项目中用到连接查询,连接查询是关系数据中最主要的查询,包括内连接、外连接等。通过连接运算符可以实现多个表查询。下面来复习一下。 正文 连接查询主要分为三种:内连接、外连...

zt15732625878
01/16
0
0
mysql多表查询

1、并(union) “并”就是把具有相同字段数目和字段类型的表合并到一起 2、笛卡尔积 笛卡尔积就是没有连接条件表关系的返回的结果 3、内连接(inner join) 针对数据库操作的运算提供了一个专门...

TsingCall
2017/10/21
0
0
杂事杂知识,

以前在写博客中,自己感觉函数,SQL查询常用的没必要多看多学习,今天想处理一个简单笛卡尔积问题,炸了!下面聊聊解决和感觉有意义的知识点 说问题拉点知识关于rownum的,这是Oracle系统查询...

长路慢
02/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

WinDbg

参考来自:http://www.cnit.net.cn/?id=225 SRV*C:\Symbols*http://msdl.microsoft.com/download/symbols ctrl + d to open dump_file Microsoft (R) Windows Debugger Version 6.12.0002.633......

xueyuse0012
今天
2
0
OSChina 周五乱弹 —— 想不想把92年的萝莉退货

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @罗马的王:分享松澤由美的单曲《地球ぎ》 很久没看圣斗士星矢了 《地球ぎ》- 松澤由美 手机党少年们想听歌,请使劲儿戳(这里) @开源中国首...

小小编辑
今天
14
1
springBoot条件配置

本篇介绍下,如何通过springboot的条件配置,控制Bean的创建 介绍下开发环境 JDK版本1.8 springboot版本是1.5.2 开发工具为 intellij idea(2018.2) 开发环境为 15款MacBook Pro 前言 很多时候,...

贺小五
今天
1
0
javascript source map 的使用

之前发现VS.NET会为压缩的js文添加一个与文件名同名的.map文件,一直没有搞懂他是用来做什么的,直接删除掉运行时浏览器又会报错,后来google了一直才真正搞懂了这个小小的map文件背后的巨大...

粒子数反转
昨天
1
0
谈谈如何学Linux和它在如今社会的影响

昨天,还在农耕脑力社会,今天已经人工智能技术、大数据、信息技术的科技社会了,高速开展并迅速浸透到当今科技社会的各个方面,Linux日益成为人们信息时代的到来,更加考验我们对信息的处理程...

linux-tao
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部